3

如果我在配置中定义:

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

我希望扩展此配置并向 Listeners 数组属性添加一个新项目,以便最终配置有效:

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

首次注册组件时必须知道“数组”的内容,还是可以检索组件注册并添加到其中?

我希望使用装饰器模式来实现我的配置,这样我就可以构建我的容器,然后根据不同场景的需要对其进行扩展。这意味着我需要能够访问已配置的组件并添加到它们。

正在考虑有一个DefaultConfig返回默认设置的类,然后是多个“ DecoratedConfig”类之一,这将扩展默认配置。

所以我会

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

DefaultConfigActivityService使用 a设置DefaultActivityListener(如示例所示)。

DecoratedConfig将识别ActivityService已创建并将其自己的 Listener 实现添加到Listeners数组 on ActivityService

谢谢。

4

3 回答 3

2

订阅Kernel.ComponentModelCreated活动。您可以从那里更改任何组件参数。看到这个。它不一定执行此操作的设施,但它很方便。

于 2009-06-02T14:42:15.703 回答
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());

然后所有组件都将通过这个类,您可以在其中更改它们的配置。在您的情况下,更改侦听器列表等(我猜这是拦截器的旧名称)

于 2014-07-23T10:29:54.320 回答
0

@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");
    }
}
于 2009-06-02T22:20:19.583 回答