2009-06-02 6 views
3

aktualisieren Wenn ich in Config definiert haben:Schloss Windsor: Wie kann ich eine Komponenten-Registrierung

container.Register(
    Component.For<X.Y.Z.IActivityService>() 
      .ImplementedBy<X.Y.Z.ActivityService>() 
      .ServiceOverrides(ServiceOverride.ForKey("Listeners").Eq(new [] { typeof(X.Y.Z.DefaultActivityListener).FullName })) 
      .LifeStyle.Transient 
); 

und ich möchte diese Konfiguration erweitern und ein neues Element in die Hörer-Array-Eigenschaft hinzufügen, so dass die endgültige Konfiguration ist effektiv:

container.Register(
    Component.For<X.Y.Z.IActivityService>() 
      .ImplementedBy<X.Y.Z.ActivityService>() 
      .ServiceOverrides(ServiceOverride.ForKey("Listeners").Eq(new [] { typeof(X.Y.Z.DefaultActivityListener).FullName, "MyOtherListenerID" })) 
      .LifeStyle.Transient 
); 

muß wissen, ich den Inhalt des „Array“, wenn zuerst die Komponente Registrierung oder kann ich die Komponente Registrierung abrufen und sie hinzufügen?

Ich möchte meine Konfiguration mit dem Decorator-Muster zu implementieren, so dass ich meinen Container erstellen und erweitern Sie es dann für verschiedene Szenarien wie erforderlich. Das heißt, ich muss auf die bereits konfigurierten Komponenten zugreifen und sie hinzufügen können.

Wurde gedacht, eine Klasse DefaultConfig zu haben, die das Standard-Setup zurückgeben und dann eine von mehreren "DecoratedConfig" -Klassen, die die Standardkonfiguration erweitern würden.

So würde ich

IWindsorContaner c = new DecoratedConfig(new DefaultConfig()).InitialiseContainer(); 

DefaultConfig würde eingerichtet haben die ActivityService mit einem DefaultActivityListener (wie im Beispiel gezeigt).

DecoratedConfig würde erkennen, dass ActivityService wurde erstellt und fügen Sie eine eigene Listener-Implementierung zum Listeners Array auf ActivityService.

Danke.

Antwort

2

Abonnieren Sie das Ereignis. Sie können jeden Komponentenparameter von dort ändern. Siehe this. Es ist nicht eine Einrichtung zu sein, die dies tut, aber es ist bequem.

+0

CompoentModel Änderung ist der Weg zu gehen. Siehe unten Testmethode. – crowleym

0

@ mausch, adusting die ComponentModel Konfiguration scheint die Lösung zu sein.

Der unten stehende Test macht effektiv, was ich benötige, ohne mich an die ComponentModelCreatedEvent anzuhängen, damit ich die Änderungen auch nach dem Erstellen des Komponentenmodells vornehmen kann.

Ich werde die Funktionalität als eine Erweiterungsmethode umschließen und versuchen, zu einer fließenden API zu passen.

[TestMethod] 
public void ArrayPropertyTestApi3() 
{ 
    using (Castle.Windsor.WindsorContainer container = new Castle.Windsor.WindsorContainer()) 
    { 
     container.Register(Component.For<Components.A>().ServiceOverrides(ServiceOverride.ForKey("I").Eq(new[] { typeof(Components.B).FullName }))); 
     container.Register(Component.For<Components.B>()); 
     container.Register(Component.For<Components.C>()); 

     IHandler h = container.Kernel.GetHandler(typeof(Components.A)); 
     if (h != null) 
     { 
      var config = h.ComponentModel.Configuration; 
      if (config != null) 
      { 
       var items = config.Children.Single(c => c.Name == "parameters") 
            .Children.Single(c => c.Name == "I") 
            .Children.Single(c => c.Name == "list") 
            as MutableConfiguration; 

       items.Children.Add(new MutableConfiguration("item", string.Format("${{{0}}}", typeof(Components.C).FullName))); 
      } 
     } 

     Components.A svc = container.Resolve<Components.A>(); 
     Assert.IsTrue(svc.I.Length == 2); 
     Assert.IsTrue(svc.I[0].Name == "B"); 
     Assert.IsTrue(svc.I[1].Name == "C"); 
    } 
} 
0

Es ist bevorzugt, die ComponentModel construction contributors mit der IContributeComponentModelConstruction Schnittstelle zu verwenden, da es die empfohlene Methode zur Konfiguration Ihrer Komponenten weiter ist.

so zu tun, würden Sie die Schnittstelle implementieren, um die Änderungen zu spezifizieren, um Konfigurations

public class ChangeConfiguration : IContributeComponentModelConstruction 
{ 
    public void ProcessModel(IKernel kernel, ComponentModel model) 
    { 
     // filter your model to match the subset you're interested in 
     // change the configuration for matching models 
    } 
} 

dann anzuwenden, bevor Sie Komponenten registrieren, Sie fügen Sie einfach die Klasse zu Ihrem Container:

container.Kernel.ComponentModelBuilder.AddContributor(new ChangeConfiguration()); 

Alle Komponenten durchlaufen dann diese Klasse, in der Sie ihre Konfiguration ändern können.In Ihrem Fall ändern Sie die Listener-Liste, etc. (Ich denke, das ist der vorherige Name der Interzeptoren)