Castello di Windsor: Come posso aggiornare una registrazione componenti
-
06-09-2019 - |
Domanda
Se ho definito in config:
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
);
e desidero estendere questa configurazione e aggiungere un nuovo elemento alla proprietà ascoltatori di matrice in modo tale che la configurazione finale è efficace:
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
);
devo conoscere il contenuto della "matrice", quando prima registrazione del componente, o posso recuperare la registrazione del componente e aggiungere ad essa?
Vorrei realizzare il mio config utilizzando il modello decorator tale che posso costruire il mio contenitore, e poi estenderlo in base alle esigenze per diversi scenari. Questo significa che ho bisogno di essere in grado di accedere ai componenti già configurati e aggiungere a loro.
pensava di avere una DefaultConfig
classe che restituisce la configurazione di default e poi uno dei più classi "DecoratedConfig
", che sarebbe estendere la configurazione di default.
Così avrei
IWindsorContaner c = new DecoratedConfig(new DefaultConfig()).InitialiseContainer();
DefaultConfig
stabilirebbe la ActivityService
con un DefaultActivityListener
(come mostrato nell'esempio).
DecoratedConfig
sarebbe riconoscere che ActivityService
era stato creato e aggiungere la propria implementazione Listener alla matrice Listeners
su ActivityService
.
Grazie.
Soluzione
sottoscrivere l'evento Kernel.ComponentModelCreated
. È possibile modificare qualsiasi parametro di un componente da lì. Vedere questo . Non sono di essere una struttura che fa questo, ma è comodo.
Altri suggerimenti
@mausch, orientamento sono la configurazione ComponentModel
sembra essere la soluzione.
Il test sotto fa effecitvely quello richiedo senza dover agganciare al ComponentModelCreatedEvent
così posso apportare le modifiche anche dopo aver creato il modello del componente.
Io avvolgere la funzionalità un metodo di estensione, e cercare di adattarsi ad un'API fluente.
[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");
}
}
È preferibile utilizzare il ComponentModel contributori costruzione con la IContributeComponentModelConstruction
interfaccia dal momento che è il modo consigliato di configurare ulteriormente i componenti.
Per fare ciò, è necessario implementare l'interfaccia per specificare le modifiche da applicare alla configurazione
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
}
}
Quindi prima di registrare i componenti, si aggiunge solo la classe per il vostro contenitore:
container.Kernel.ComponentModelBuilder.AddContributor(new ChangeConfiguration());
Tutti i componenti saranno poi passare attraverso questa classe, in cui è possibile cambiare la loro configurazione. Nel tuo caso changeing lista ascoltatore, ecc (credo che questo è il nome precedente di intercettori)