2016-07-14 19 views
1

Ich habe eine Komponente mit mehreren Abhängigkeiten:Kann ich untergeordnete Container als Factory für Komponenten mit komplexen Abhängigkeiten verwenden?

class Service 
{ 
    public Service(IDependencyA a, IDependencyB b, ...) { ... } 
} 

wo einige Abhängigkeiten einzelne Implementierung haben:

class CommonDependencyA : IDependencyA 
{ 
    ... 
} 

und einige haben mehrere Implementierungen:

class FooDependencyB : IDependencyB 
{ 
    public FooDependencyB(IDependencyC c, ...) { ... } 
} 

class BarDependencyB : IDependencyB 
{ 
    public BarDependencyB(IDependencyC c, ...) { ... } 
} 

class FooDependencyC : IDependencyC 
{ 
    ... 
} 

class BarDependencyC : IDependencyC 
{ 
    ... 
} 

Manchmal möchte ich lösen Service Klasse mit "Bar" Implementierungen, während ich andere Male "Foo" Implementierungen möchte.

Ich dachte über die Verwendung von Kinder-Container, um die Registrierung zu tun. So kann ich etwas tun könnte, wie:

public Service CreateService(IWindsorContainer parent, FooBarType type) 
{ 
    using(IWindsorContainer child = SetupChildContainer(parent)) 
    { 
     if (type == FooBarType.Foo) 
     { 
      child.Register(Component.For<IDependencyC>.ImplementedBy<FooDependencyC>().LifeStyle.Transient); 
      child.Register(Component.For<IDependencyB>.ImplementedBy<FooDependencyB>().LifeStyle.Transient); 
      ... 
     } 
     else 
     { 
      //register "Bar" implementations 
     } 
     child.Register(Component.For<Service>.LifeStyle.Transient); 
     return child.Resolve<Service>(); 
    } 
} 

dann kann ich diese Methode in eine Fabrik, Refactoring und diese Fabrik innerhalb des übergeordneten Container registrieren.

Was ich nicht über diesen Ansatz gefällt, ist, dass jedes Mal, wenn ich brauche einen Service zu lösen, ich habe die Registrierung zu tun. Ich habe auch eine Behauptung gelesen, dass die Verwendung eines Kindercontainers fast immer die falsche Lösung ist. Also, mache ich es falsch? Gibt es einen besseren Ansatz? Ich würde lieber registrieren alle Komponenten einmal, dann wie etwas nennen:

var fooService = container.Resolve<Service>(new []{FooBarType.Foo}); 

und machen Widsor die richtigen Abhängigkeiten herauszufinden. Aber ich weiß nicht, wie ich die Registrierung machen soll, damit das funktioniert.

+0

Ich denke, die Tatsache, dass Sie Ihren Ansatz nicht mögen, legt nahe, dass die Verwendung von Kindercontainern übertrieben ist. Sie können versuchen, typisierten Fabrik zu verwenden: http://stackoverflow.com/questions/14318582/windsor-resolve-dependencies-using-a-key oder mit Parametern zu beheben: http://stackoverflow.com/questions/18048229/burg-windsor-resolve-method-warum-pass-argumente-was-sind-sie-für – Thuan

Antwort

0

I ended up namens Abhängigkeiten mit:

container.Register(Component.For<IDependencyA>().ImplementedBy<CommonDependencyA>()); 
container.Register(Component.For<IDependencyC>().ImplementedBy<FooDependencyC>() 
          .Named("FooDependencyC")); 
container.Register(Component.For<IDependencyB>().ImplementedBy<FooDependencyB>() 
          .Named("FooDependencyB") 
          .DependsOn(Dependency.OnComponent(typeof(IDependencyC), "FooDependencyC")); 
container.Register(Component.For<Service>(). 
          .Named("FooService") 
          .DependsOn(Dependency.OnComponent(typeof(IDependencyB), "FooDependencyB")); 

Nicht das, was ich hatte gehofft, für (I mit Namen hassen), aber gut genug, um in meinem Fall.