【问题标题】:Castle Windsor Fluent API: Define Array with Single item as DependencyCastle Windsor Fluent API:将具有单个项目的数组定义为依赖项
【发布时间】:2010-10-30 09:06:43
【问题描述】:

鉴于此 XML 配置(有效)

<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" /> 

我已转换为使用以下 fluent 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
);

当我现在尝试解析 X.Y.Z.ActivityService 的实例时,Windsor 会在 Castle.MicroKernel.SubSystems.Conversion.ArrayConverter.PerformConversion(String, Type) 中抛出 NotImplementedException

PerformConversion方法的实现是:

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

我应该补充一点,如果我删除 ServiceOverrides 调用,所有行为都会按预期进行。因此,我连接 Listeners 参数的方式特别有问题。顺便说一下,监听器是一个属性,而不是构造函数参数。

看到 XML 配置按预期工作,我如何最好地使用 fluent API(没有实现 PerformConversion 方法)以达到相同的结果?

我使用的是 2.0 版。

编辑

我将把问题扩展到您如何在代码中实现此配置,无论是否使用 fluent API。

更新

如果您尝试将单个元素分配给数组属性,就会出现问题。下面提供了单元测试来说明问题。

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

问题仍然存在。

谢谢。

【问题讨论】:

    标签: api castle-windsor fluent


    【解决方案1】:
    [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 需要知道参数 listeners 是一个数组,如果您只传递“listener”,它会假定参数是标量并抛出,因为它无法将标量转换为数组。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多