2016-07-27 60 views
1

我正在使用Ninject來注入依賴關係。 我有下面的類結構:C#Ninject參數綁定

public interface IClass 
{ 
} 

public class Class: IClass 
{ 
public virtual void Method(Object context) 
{ 
    -------- 
} 
} 

public class Class1: IClass 
{ 
public override void Method(Object context) 
{ 
    -------- 
} 
} 

public class Class2: IClass 
{ 
public override void Method(Object context) 
{ 
    -------- 
} 
} 

context包含 - HasBilling,HasPayment性質與其他更多的屬性一起。

Method()通過使用工廠模式調用:

public interface IClassFactory 
    { 
     IClass CreateClass(); 
    } 

_classFactory.CreateClass().Method(....) 

所以當參數HasBilling等於true然後我要引用的Class1實施Method(),同樣的,如果HasPayment等於真正的Class2實施Method()必須調用。

使用Ninject綁定,我想這些綁定,但是沒有一個工作:

Bind<IClass>().To<Class1>().When(x => x.Target.Member.Name.Contains("HasBilling").Equals(true)); 

想這一點,但沒有運氣:

Bind<IClass>().To<Class1>().WithMetadata("HasBilling", true); 

請能有人幫我什麼綁定需要設置爲基於參數值(HasBilling,HasPayment)調用Class1,Class2方法(Method)。

很多感謝,

感謝, WH

回答

0

如果您context是必要的,以確定哪些具體類型來加載,那麼你就需要將它要麼傳遞給你的具體類或工廠。 AFAIK沒有辦法讓Ninject檢查你的調用鏈來說「方法X將被調用,所以我需要使用這些信息來確定使用哪個具體的類」。

如果你改變你的工廠,這個問題,因爲很簡單:

interface IClassFactory 
{ 
    IClass CreateClass(Object context) 
} 

class ClassFactory : IClassFactory 
{ 
    IClass CreateClass(Object context) 
    { 
     if (context.HasBilling) 
      return new Class1(); 

     // default case 
     return new Class2(); 
    } 
} 

然後,你將與消費:

IClassFactory classFactory; // injected 
object context; 

classFactory.CreateClass(context).Method(); 

另一種方法是使用代理模式。 IClass保持不變,取消IClassFactory。相反,你使用代理:

public class ClassProxy : IClass 
{ 
    void Method(Object context) 
    { 
     if (context.HasBilling) 
      new Class1().Method(context); 
     else 
     //etc 
    } 
} 

在你籽粒你會爲這樣組裝起來:

kernel.Bind<IClass>().To<ClassProxy>(); 

你想也需要確保你的實現是不是在內核勢必IClass。 (所以請確保你有不要kernel.Bind<IClass>().To<Class1>()

如果你想利用DI爲您的實現類,但是,你可以讓他們自我綁定(kernel.Bind<Class1>().ToSelf()),然後你ClassProxy可以把它們作爲依賴:

class ClassProxy : IClass 
{ 
    private readonly Class1 _class1;  
    private readonly Class2 _class2; 

    public ClassProxy(Class1 class1, Class2 class2){ 
     _class1 = class1; 
     _class2 = class2; 
    } 

    void Method(object context) 
    { 
     if (context.HasBilling) 
      _class1.Method(context); 
    }