Windsor Lock Fluent API: Defining an Array with a Single Element as a Dependency

Given this XML configuration (which works)

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

I switched to using a free API as shown below (which does not work):

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

When I try to resolve an instance now X.Y.Z.ActivityService, Windsor throws a NotImplementedExceptioninto Castle.MicroKernel.SubSystems.Conversion.ArrayConverter.PerformConversion(String, Type).

Implementation of the PerformConversion method:

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

I must add that if I remove the call ServiceOverrides, everything will behave as expected. So there is something wrong with the way I connect the Listeners parameter. Listeners, by the way, are a property in contrast to the constructor parameter.

Seeing how the XML configuration works as expected, what is the best way to use the free API (except for the implementation of the PerformConversion method) to achieve the same result?

2.0.

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

.

.

+1
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 , - , "", , , .

+3

Source: https://habr.com/ru/post/1732985/


All Articles