2016-07-27 110 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); 
    }