Ninject - 将不同的接口实现绑定到相同的 class

Ninject - Bind different interfaces implementations to the same class

我是 DI 的新手(使用 Ninject)并且刚刚开始学习这些概念,但是为了理解这一点我已经摸不着头脑了一段时间:

假设我在我的程序中对相同的 class 有不同的用法(下面示例中的 ProcessContext)。

在第一个 class (SomeClass) 中:我想将 Implement1 注入 ProcessContext 实例。

在第二个 class (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>();            
    }
}

您可以通过这种方式轻松地注入额外的构造函数参数:

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

目前,我无法访问 ninject。如果它没有按预期工作,请告诉我。

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

您可以为此使用 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");