我正在尝试转换获取某种类型消息的工厂类,并将该消息类型的处理器解析为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的以下blogpost和documentation,我创建了以下内容:
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 []'。
我做错了什么以及如何改进代码?
答案 0 :(得分:1)
这很简单。正如异常消息所示,您的代理不会实现非通用IProcessor
接口。您还需要在这些组件上提供服务。
此外,您的选择器会告诉Windsor您所追求的是单个项目,而签名意味着您需要一个集合。因此,转换失败是因为您将单个项目转换为数组类型。
所以你的选择器的方法应该有
.MakeArrayType()
最后。