2017-01-25 52 views
1

我是新来的DI(使用Ninject)和刚开始学的概念,但我一直在抓我的头一会儿就明白这一点:Ninject - 绑定不同的接口实现同一类

假设我的程序中有相同类的不同用法(下例中为ProcessContext)。

第一类(SomeClass):我想注入Implement1ProcessContext实例。

第二类(SomeOtherClass):我想将Implement2注入ProcessContext实例。

我该如何使用Ninject来执行绑定?

public class Implement1 : IAmInterace 
{ 
    public void Method() 
    { 
    } 
} 

public class Implement2 : IAmInterace 
{ 
    public void Method() 
    { 
    } 
} 

public class ProcessContext : IProcessContext 
{ 
    IAmInterface iamInterface; 
    public ProcessContext(IAmInterface iamInterface) 
    { 
     this.iamInterface = iamInterface; 
    } 
} 

public class SomeClass : ISomeClass 
{ 
    public void SomeMethod() 
    { 
     // HERE I WANT TO USE: processcontext instance with Implement1 
     IProcessContext pc = kernel.Get<IProcessContext>();    
    } 
} 

public class SomeOtherClass : ISomeOtherClass 
{ 
    public void SomeMethod() 
    { 
     // HERE I WANT TO USE: processcontext instance with Implement2 
     IProcessContext pc = kernel.Get<IProcessContext>();    
    } 
} 
+0

这听起来像你需要的东西像[策略模式](http://stackoverflow.com/a/32415954/181087),使您可以选择基于参数的实现。这是另一个[示例](http://stackoverflow.com/a/31971691/181087),它将抽象工厂的相同模式组合在一起,以实时获取实例。 – NightOwl888

回答

0

您可以使用named bindings

例如是这样的:

Bind<IProcessContext>() 
    .To<ProcessContext>() 
    .WithConstructorArgument("iamInterface", context => Kernel.Get<Implement1>()) 
    .Named("Imp1"); 

Bind<IProcessContext>() 
    .To<ProcessContext>() 
    .WithConstructorArgument("iamInterface", context => Kernel.Get<Implement2>()) 
    .Named("Imp2"); 

kernel.Get<IProcessContext>("Imp1"); 
+0

谢谢! 你可以进一步解释如何用SimpleInjector来做到这一点吗? – ohadinho

+1

@ohadinho对不起,我没有任何SimpleInjector的经验。你应该为那个图书馆开一个新的问题。 –

+0

发现在SimpleInjector中存在基于上下文的注入: http://simpleinjector.readthedocs.io/en/latest/advanced.html#context-based-injection – ohadinho

0

您可以用这种方式很容易注入额外的构造函数参数:

public void SomeMethod() 
{ 
    var foo = new Ninject.Parameters.ConstructorArgument("iamInterface", new Implement2()); 
    IProcessContext pc = kernel.Get<IProcessContext>(foo);    
} 

现在,我不必ninject访问。所以告诉我它是否按预期工作。

+0

在我的例子中,我只使用了2个接口。发生什么“富”有相同的问题?如果Implement2在构造函数中获取IAmInterface2,我将再次需要设置ConstructorArgument。 有没有更简单的方法? – ohadinho

+0

@ohadinho在你的情况下,你想传递一个具体类型到'IProcessContext'。其实你不想使用DI容器。但是如果'Implement2'需要一些其他接口,因为它是参数,你必须注入所需的参数。我的意思是通常你从'Ninject'本身得到你的实例,让'Ninject'将参数传递给它。 – Feriloo

0

这是不可能的,因为Ninject无法知道要返回哪个实现。然而;如果您通过传入变量来创建IProcessContext的新实例,那么Ninject将使用适当的构造函数查找实现并返回该实例。

相关问题