Windsor Castle: How to Update Component Registration

If I defined 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
);

and I want to expand this configuration and add a new element to the Listeners array property so that the final configuration is efficient:

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
);

Do I have to know the contents of the "array" when I first register the component, or can I get the registration of the component and add to it?

I want to implement my configuration using a decorator template so that I can create my container and then expand it as needed for different scenarios. This means that I need to have access to the components already configured and add to them.

DefaultConfig, , "DecoratedConfig", .

,

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

DefaultConfig ActivityService DefaultActivityListener ( ).

DecoratedConfig , ActivityService Listener Listeners ActivityService.

.

+3
3

Kernel.ComponentModelCreated. . . this. , , .

+2

@mausch, , ComponentModel .

, , ComponentModelCreatedEvent, .

API.

[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

ComponentModel IContributeComponentModelConstruction, .

, ,

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
    }
}

, , :

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

All components will go through this class, where you can change their configuration. In your case, changing the list of listeners, etc. (I think this is the previous name of the interceptors)

0
source

Source: https://habr.com/ru/post/1709587/


All Articles