温莎通用型工厂

时间:2011-04-26 14:20:19

标签: castle-windsor typed-factory-facility

我正在尝试转换获取某种类型消息的工厂类,并将该消息类型的处理器解析为Typed Factory Facility的实现。

我开始的代码是:

public interface IProcessor<in T> where T : Message
{
    void Process(T message);
}

public class ProcessorFactory : IProcessorFactory
{
    private readonly IKernel _container;

    public ProcessorFactory(IKernel container)
    {
        if (container == null) throw new ArgumentNullException("container");

        _container = container;
    }

    public void Process(Message message)
    {
        // Create a specific message processor type
        var processorType = typeof(IProcessor<>).MakeGenericType(message.GetType());

        // Resolve all processors for that message
        var processors = _container.ResolveAll(processorType);

        foreach (var processor in processors)
        {
            processor.GetType().GetMethod("Process").Invoke(processor, new[] { message });
        }
    }

public class ProcessorInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
                Component.For<IProcessorFactory>().ImplementedBy<ProcessorFactory>(),
                AllTypes.FromThisAssembly().BasedOn(typeof(IProcessor<>)).WithService.FirstInterface().
                    AllowMultipleMatches());
    }
}

根据Castle Windsor的以下blogpostdocumentation,我创建了以下内容:

public interface IProcessor
{
    void Process();
}

public interface IProcessor<T> where T : Message
{
    /// <summary>
    /// Message to process
    /// </summary>
    T Message { get; set; }
}

public interface IProcessorFactory
{
    IProcessor[] GetAllProcessorsForMessage(Message message);
}

public class ProcessorInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.AddFacility<TypedFactoryFacility>()
            .Register(
                Component.For<ProcessorSelector, ITypedFactoryComponentSelector>(),
                Component.For<AutoReleaseProcessorInterceptor>(),

                AllTypes.FromThisAssembly()
                    .BasedOn(typeof(IProcessor<>))
                    .WithService.Base()
                    .Configure(c => c.LifeStyle.Is(LifestyleType.Transient)
                        .Interceptors<AutoReleaseProcessorInterceptor>()),

                Component.For<IProcessorFactory>().AsFactory(f => f.SelectedWith<ProcessorSelector>()));
    }
}

public class ProcessorSelector : DefaultTypedFactoryComponentSelector
{
    protected override Type GetComponentType(MethodInfo method, object[] arguments)
    {
        return typeof(IProcessor<>).MakeGenericType(arguments[0].GetType());
    }
}

当我致电factory.GetAllProcessorsForMessage(new ExampleMessage())时,我收到以下错误:

  

无法将类型为'Castle.Proxies.IProcessor`1Proxy'的对象强制转换为'MyNamespace.Processors.IProcessor []'。

我做错了什么以及如何改进代码?

1 个答案:

答案 0 :(得分:1)

这很简单。正如异常消息所示,您的代理不会实现非通用IProcessor接口。您还需要在这些组件上提供服务。

此外,您的选择器会告诉Windsor您所追求的是单个项目,而签名意味着您需要一个集合。因此,转换失败是因为您将单个项目转换为数组类型。

所以你的选择器的方法应该有

.MakeArrayType()最后。