2009-06-02 2 views
3

를 업데이트 할 수 있습니다 방법 :성 윈저 : 내가 설정에 정의 된 경우 I는 구성 요소 등록을

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"클래스 중 하나 이상을 반환합니다.

그래서 (예에서와 같이)를 DefaultActivityListenerActivityService을 설정합니다

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

DefaultConfig있을 것입니다.

DecoratedConfigActivityService이 작성되었음을 인식하고 배열에 ActivityService에 자체 리스너 구현을 추가합니다.

감사합니다.

답변

2

Kernel.ComponentModelCreated 이벤트를 구독하십시오. 거기에서 모든 구성 요소 매개 변수를 변경할 수 있습니다. this을 참조하십시오. 이 작업을 수행하는 시설은 이 아니며이지만 편리합니다.

+0

CompoentModel 수정이 최선의 방법입니다. 아래의 시험 방법을 참조하십시오. – crowleym

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"); 
    } 
} 
0

IContributeComponentModelConstruction 인터페이스로 ComponentModel construction contributors를 사용하는 것이 바람직하다.

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

:

이렇게하려면, 당신은

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

이 그런 다음 구성 요소를 등록하기 전에, 당신은 당신의 컨테이너에 클래스를 추가 구성에 적용 할 변경 사항을 지정하는 인터페이스를 구현하는 것 그러면 모든 구성 요소가이 클래스를 통과하여 구성을 변경할 수 있습니다.귀하의 경우 리스너 목록을 변경하는 등 (나는 이것이 요격기의 이전 이름이라고 생각합니다)