如果我在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
);
我希望扩展此配置并向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();
DefaultConfig
会设置ActivityService
DefaultActivityListener
(如示例所示)。
DecoratedConfig
会认识到已创建ActivityService
并将自己的侦听器实现添加到Listeners
上的ActivityService
数组。
感谢。
答案 0 :(得分:2)
订阅Kernel.ComponentModelCreated
活动。您可以从那里更改任何组件参数。见this。 不是成为这样做的设施,但它很方便。
答案 1 :(得分:0)
@mausch,ad {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");
}
}
答案 2 :(得分:0)
最好将ComponentModel construction contributors 与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());
然后,所有组件都将通过此类,您可以在其中更改其配置。在你的情况下改变监听器列表等(我猜这是拦截器的先前名称)