Frage

Ich benutze S#ARP -Architektur, die Windsor Castle für IOC verwendet. Ich habe jetzt einen neuen Controller bekommen, der im Gegensatz zu allen anderen Controllern im Projekt eine andere Implementierung derselben Schnittstellen benötigt. IE Alle Controller verwenden ProductsRepository: iProductsRepository als Implementierung, das neue muss jedoch spezifische Produkte verwenden.

Wie konfiguriere ich es, um dies automatisch zu erkennen und zu verwalten? Entweder in reiner Windsor -Art oder mit ASP.NET -MVC -Hilfe (z. B. in meiner Custom Controllers Factory).

Ok sieht so aus, als würde ich Unterkontainer brauchen. Immer noch am suchen.

War es hilfreich?

Lösung

Ein einfacherer und viel einfacherer Weg wäre, Windsors Service -Overrides zu verwenden.

ZB registrieren Sie Ihre Repos wie SO:

container.Register(Component.For<IProductsRepository>
                     .ImplementedBy<ProductsRepository>()
                     .Named("defaultProductsRepository"),
                   Component.For<IProductsRepository>
                     .ImplementedBy<SpecificProductsRepository>()
                     .Named("specificProductsRepository"));

Dies wird sicherstellen, dass die Standardimplementierung ist ProductsRepository. Fügen Sie nun für Ihren spezifischen Controller einen Service -Override so hinzu:

container.Register(Component.For<NewController>()
     .ServiceOverrides(ServiceOverride
          .ForKey("productsRepository")
          .Eq("specificProductsRepository"));

Sie können die Dokumente lesen hier.

Bearbeiten: Wenn Sie Ihre Repositories registrieren möchten AllTypes, Sie können den Registrierungsschlüssel wie SO einstellen:

container.Register(AllTypes.[how you used to].Configure(c => c.Named(GetKey(c)));

wo GetKey EG könnte so etwas sein wie:

public string GetKey(ComponentRegistration registration)
{
    return registration.Implementation.Name;
}

Andere Tipps

Ok, heutzutage neige ich dazu, meine eigenen Fragen zu beantworten ... also hier ist es für diejenigen, die es brauchen.

     // create subcontainer with specific implementation
     var mycontainer = new WindsorContainer();
     mycontainer.Register(AllTypes.Pick()
        .FromAssemblyNamed("My.Data")
        .WithService.FirstInterface()
        .Where(x => x.Namespace == "My.Data.Custom")
        .Configure(x => x.LifeStyle.Is(LifestyleType.PerWebRequest)));
     container.AddChildContainer(mycontainer);

     ControllerBuilder.Current.SetControllerFactory(new ExtendedControllerFactory(
        new Dictionary<string, IWindsorContainer> { {"", container}, {"Lm", mycontainer} }));

Die Controller Factory wählt den entsprechenden Container basierend auf dem Namen aus. Die größte Herausforderung, die es am Ende der Anfrage als entsprechende Container (Controller) aufzurufen, dh daran erinnert, welcher Container zum Instanziieren von Controller verwendet wurde. Dies kann jedoch auf verschiedene Arten gelöst werden - denken Sie an threadspezifische (in httpcontext), denken Sie in der BaseController -Eigenschaft, denken Sie daran, in internem Wörterbuch usw.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top