Castle Windsor : 구성 요소 등록을 어떻게 업데이트 할 수 있습니까?
-
06-09-2019 - |
문제
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
);
그리고이 구성을 확장하고 최종 구성이 효과적으로 다음과 같이 리스너 배열 속성에 새 항목을 추가하고 싶습니다.
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
a DefaultActivityListener
(예에서 볼 수 있듯이).
DecoratedConfig
그것을 인식 할 것입니다 ActivityService
자체 청취자 구현을 만들었고 Listeners
배열 켜기 ActivityService
.
감사.
해결책
구독하십시오 Kernel.ComponentModelCreated
이벤트. 거기에서 구성 요소 매개 변수를 변경할 수 있습니다. 보다 이것. 그렇지 않습니다 가지다 이 작업을 수행하는 시설이지만 편리합니다.
다른 팁
@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");
}
}
사용하는 것이 바람직합니다 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());
그런 다음 모든 구성 요소 가이 클래스를 통과하여 구성을 변경할 수 있습니다. 귀하의 경우에는 청취자 목록 등을 변경합니다 (이것은 인터셉터의 이전 이름이라고 생각합니다).