Castle.MicroKernel.ComponentNotFoundException с TypedFactoryFacility

У меня возникли проблемы с разрешением ITcpServer при использовании TypedFactoryFacility. Похоже, что Windsor не находит подходящего компонента, который будет возвращен с завода для интерфейса. Что характерно для моего случая, так это то, что интерфейс ITcpServer не является универсальным, в то время как классы, реализующие его, являются общими.

Следующий код выдает при запуске:

Необработанное исключение: Castle.MicroKernel.ComponentNotFound Exception: Компонент для поддержки службы ConsoleApplication1.StandardTcpServer`1 не найден в Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(служба типов, аргументы CastlePlayersFilence, IRe), тип обслуживания..TypedFactory.AbstractInvocation.Proceed()
в Castle.Proxies.ITcpServerFactoryProxy.Create[T](String serverType, T что-то)

Код:

class Program
{
    static void Main(string[] args)
    {
        IWindsorContainer container = new WindsorContainer();
        container.Install(new MyWindsorInstaller());

        var f = container.Resolve<ITcpServerFactory>();
        var tcpServer = f.Create("standard", "something");
        tcpServer.Start();
    }
}

 public class MyWindsorInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.AddFacility<TypedFactoryFacility>();
        container.Register(
            Component.For<ITcpServer>().ImplementedBy(typeof(LibUvTcpServer<>)),
            Component.For<ITcpServer>().ImplementedBy(typeof(StandardTcpServer<>)),
            Component.For<ITcpServerFactory>().AsFactory(c => c.SelectedWith(new TcpServerComponentSelector()))
            );
    }
}

public class TcpServerComponentSelector : DefaultTypedFactoryComponentSelector
{
    protected override Type GetComponentType(System.Reflection.MethodInfo method, object[] arguments)
    {
        var serverType = (string)arguments.First();
        return serverType == "standard" ? typeof (StandardTcpServer<>) : typeof(LibUvTcpServer<>);
    }
}

public interface ITcpServerFactory
{
    ITcpServer Create<T>(string serverType, T something);
}

public class StandardTcpServer<T> : ITcpServer
{
    public void Start()
    {
        Console.WriteLine("Started...");
    }
}

public class LibUvTcpServer<T> : ITcpServer
{
    private readonly T something;

    public LibUvTcpServer(T something)
    {
        this.something = something;
    }

    public void Start()
    {
        Console.WriteLine("Started...");
    }
}

public interface ITcpServer
{
    void Start();
}

Любая помощь в решении проблемы будет принята с благодарностью.

1 ответ

Решение

Измените следующее:

protected override Type GetComponentType(System.Reflection.MethodInfo method, object[] arguments)
{
    var serverType = (string)arguments.First();
    if (serverType == "standard") 
    {
        return typeof(StandardTcpServer<>).MakeGenericType(arguments[1].GetType());
    }
    else
    {
        return typeof(LibUvTcpServer<>).MakeGenericType(arguments[1].GetType());
    }
}

и регистрация:

Component.For<ITcpServer>().Forward(typeof(LibUvTcpServer<>)).ImplementedBy(typeof(LibUvTcpServer<>)),
Component.For<ITcpServer>().Forward(typeof(StandardTcpServer<>)).ImplementedBy(typeof(StandardTcpServer<>)),

или если вам нужно только решить через фабрику:

Component.For(typeof(LibUvTcpServer<>)),
Component.For(typeof(StandardTcpServer<>)),

Удачи,

Marwijn.

Другие вопросы по тегам