简体   繁体   中英

Ninject - Bind different interfaces implementations to the same class

I'm new to DI (using Ninject) and just started to learn the concepts, but I've been scratching my head for a while to understand this:

Suppose I have DIFFERENT usage of the same class in my program ( ProcessContext in the example below).

In the first class ( SomeClass ) : I would like to inject Implement1 to ProcessContext instance.

In the second class ( SomeOtherClass ) : I would like to inject Implement2 to ProcessContext instance.

How should I perform the bindings using 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>();            
    }
}

You can inject additional constructor parameters easily in this way:

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

For now, I don't have access to ninject . So tell me if it doesn't work as expected.

This is not possible as Ninject has no way of knowing which implementation to return. However; if you create a new instance of your IProcessContext by passing in a variable then Ninject will look for the implementation with the appropriate constructor and return that one.

You could use named bindings for this.

eg something like:

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");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM