2016-06-14 23 views
2

Ich versuche Ninject zu lösen, um einen Abhängigkeitsbaum aufzulösen, der abhängig von der Anzahl der Bindungen einer Abhängigkeit mehrere Objekte erstellen muss.Gibt es eine Möglichkeit, Mehrfacheinspritzung zu propagieren?

Zum Beispiel nehme ich diese Art System haben:

public class A : IA 
{ 
    public A(IB[] bs) { /* ... */ } 
} 

public class B : IB 
{ 
    public B(IC c) { /* ... */ } 
} 

public class C1 : IC 
{ 
    public C1() { /* ... */ } 
} 

public class C2 : IC 
{ 
    public C2() { /* ... */ } 
} 

public interface IA { } 
public interface IB { } 
public interface IC { } 

Kann ich Ninject konfigurieren, so etwas zu tun?

var a = new A(new IB[] 
{ 
    new B(new C1()), 
    new B(new C2()) 
}); 

Ich mag keine IB Implementierung erstellen, die mehr IC-Typen nimmt, weil IB logisch auf der Zusammenarbeit mit einem einzigen IC-Typ gebunden ist. Es ist viel einfacher, mehrere Instanzen von IB eine Ebene höher zu behandeln.

Ich konnte nur hoffen, tun dies funktionieren würde:

var kernel = new StandardKernel(); 
kernel.Bind<IC>().To<C1>(); 
kernel.Bind<IC>().To<C2>(); 
kernel.Bind<IB>().To<B>(); 
kernel.Bind<IA>().To<A>(); 

var a = kernel.Get<IA>(); 

Aber es gibt eine Ausnahme aus:

Error activating IC 
More than one matching bindings are available. 
Matching bindings: 
    1) binding from IC to C1 
    2) binding from IC to C2 
Activation path: 
    3) Injection of dependency IC into parameter c of constructor of type B 
    2) Injection of dependency IB into parameter bs of constructor of type A 
    1) Request for IA 
+0

Ninject könnte es tun, solange Sie keine zirkulären Abhängigkeiten haben. – Win

+0

IMO, Sie haben die Grenze überschritten, wo [Pure DI] (http://blog.ploeh.dk/2014/06/10/pure-di/) eine bessere Alternative als die Verwendung eines DI-Containers wird. Sie erstellen im Grunde ein "komplexes Objektdiagramm". Siehe meinen Artikel hier für weitere Details: http://criticalsoftwareblog.com/index.php/2015/08/23/why-di-containers-fail-with-complex-object-graphs/ –

+0

Eine Fabrik, die zuerst a ausspuckt 'C1', dann würde' C2' den Trick machen. – spender

Antwort

0

Eine Möglichkeit besteht darin, mehrere Bindungen für alle Kombinationen von IB + IC zu erstellen:

var kernel = new StandardKernel(); 
kernel.Bind<IB>().To<B>() 
    .WithParameter(
     new TypeMatchingConstructorArgument(
      typeof(IC), 
      (ctx, target) => ctx.Kernel.Get<C1>())); 
kernel.Bind<IB>().To<B>() 
    .WithParameter(
     new TypeMatchingConstructorArgument(
      typeof(IC), 
      (ctx, target) => ctx.Kernel.Get<C2>())); 
kernel.Bind<IA>().To<A>(); 

var a = kernel.Get<IA>(); 
Verwandte Themen