2009-06-01 45 views
1

與單項定義數組鑑於這種XML配置(工作)城堡溫莎流利的API:作爲依賴

<component type="X.Y.Z.ActivityService, X.Y.Z.Services" id="X.Y.Z.ActivityService" lifestyle="transient"> 
    <parameters> 
    <Listeners> 
     <array> 
     <item>${DefaultActivityListener}</item> 
     </array> 
    </Listeners> 
    </parameters> 
</component> 

<component type="X.Y.Z.DefaultActivityListener, X.Y.Z.Services" id="DefaultActivityListener" lifestyle="transient" /> 

我已經轉換成使用流利的API如下(不工作):

Container.Register(
    Component.For<X.Y.Z.ActivityService>() 
    .ServiceOverrides(
     ServiceOverride.ForKey("Listeners").Eq(typeof(X.Y.Z.DefaultActivityListener).Name)) 
    .LifeStyle.Transient 
); 

Container.Register(
    Component.For<X.Y.Z.DefaultActivityListener>() 
    .Named("DefaultActivityListener") 
    .LifeStyle.Transient 
); 

當我現在嘗試解決​​的一個實例時,Windsor在Castle.MicroKernel.SubSystems.Conversion.ArrayConverter.PerformConversion(String, Type)中拋出NotImplementedException

的PerformConversion方法的實現是:

public override object PerformConversion(String value, Type targetType) 
{ 
    throw new NotImplementedException(); 
} 

我要補充一點,如果我刪除ServiceOverrides通話,所有行爲與預期相同。所以在我接聽Listeners參數的時候有一些特別的錯誤。順便提一下,Listeners是一個屬性,而不是構造函數參數。

由於XML配置按預期工作,我如何才能最好地使用流利的API(短實施PerformConversion方法)以達到相同的結果?

我正在使用版本2.0。

編輯

我將延長問題,你將如何實現這個代碼的配置,使用或不使用流暢的API。

UPDATE

它出現的問題,如果你試圖單個元素分配給數組屬性時發生。下面提供的單元測試來說明問題。

namespace Components 
{ 
    public class A 
    { 
     public I[] I { get; set; } 
    } 

    public interface I 
    { 
     string Name { get; } 
    } 

    public class B : I 
    { 
     public string Name { get { return "B"; } } 
    } 

    public class C : I 
    { 
     public string Name { get { return "C"; } } 
    } 
} 


[TestMethod] 
public void ArrayPropertyTestApi() 
{ 
    //PASSES 
    using (Castle.Windsor.WindsorContainer container = new Castle.Windsor.WindsorContainer()) 
    { 
     container.Register(Component.For<Components.A>().ServiceOverrides(ServiceOverride.ForKey("I").Eq(typeof(Components.B).FullName, typeof(Components.C).FullName))); 
     container.Register(Component.For<Components.B>()); 
     container.Register(Component.For<Components.C>()); 

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

[TestMethod] 
public void ArrayPropertyTestApi2() 
{ 
    //FAILS 
    using (Castle.Windsor.WindsorContainer container = new Castle.Windsor.WindsorContainer()) 
    { 
     container.Register(Component.For<Components.A>().ServiceOverrides(ServiceOverride.ForKey("I").Eq(typeof(Components.B).FullName))); 
     container.Register(Component.For<Components.B>()); 
     container.Register(Component.For<Components.C>()); 

     Components.A svc = container.Resolve<Components.A>(); //Throws NotImplementedException 
     Assert.IsTrue(svc.I.Length == 1); 
     Assert.IsTrue(svc.I[0].Name == "B"); 
    } 
} 

問題依然存在。

謝謝。

回答

3
[TestFixture] 
public class WindsorTests { 

    [Test] 
    public void ArrayConfig() { 
     var container = new WindsorContainer(); 
     container.Register(Component.For<Listener>().Named("listener")); 
     container.Register(Component.For<ActivityService>() 
      .ServiceOverrides(ServiceOverride.ForKey("listeners").Eq(new[] {"listener"}))); 
     var service = container.Resolve<ActivityService>(); 
     Assert.AreEqual(1, service.Listeners.Length); 
    } 
} 

public class Listener {} 

public class ActivityService { 
    public Listener[] Listeners { get; set; } 
} 

這裏的關鍵部分是new[] {"listener"}。 MicroKernel需要知道參數監聽器是一個數組,如果僅傳遞「偵聽器」,則它假定該參數是標量並拋出,因爲它無法將標量轉換爲數組。

+0

@mausch - 就是這樣,謝謝。有沒有關於這方面的文件,我錯過了,如果是的話,你能指出我在正確的方向,因爲我有我需要回答的另一個問題,將很快張貼在SO上。 – crowleym 2009-06-02 08:59:48