这里是我的情况:
public static class DomainCommandProcessor
{
public static void Dispatch<T>(T command) where T : IDomainCommand
{
var serviceLocator = ServiceLocator.Current;
var handler = serviceLocator.GetInstance<IDomainCommandHandler<T>>();
if (handler != null)
handler.Handle(command);
}
}
public class FakeGenericCommand<T1, T2> : IDomainCommand
{
public FakeGenericCommand(T1 first, T2 second)
{
First = first;
Second = second;
}
public T1 First { get; private set; }
public T2 Second { get; private set; }
}
public class FakeGenericCommandHandler<T1, T2> : IDomainCommandHandler<FakeGenericCommand<T1, T2>>
{
public void Handle(FakeGenericCommand<T1, T2> command)
{
// something interesting
}
}
用法:
DomainCommandProcessor.Dispatch(new FakeGenericCommand<string, string>("hi", "there"))
我不能让温莎注册权。 非常适合我所有的非通用命令的以下工作:
container.Register(Classes.FromAssemblyNamed(namespaceName)
.BasedOn(typeof(IDomainCommandHandler<>))
.WithService.AllInterfaces()
.LifestyleTransient());
如果我直接注册的每个可能的实现,它的工作原理,但显然是次优的:
container.Register(
Component.For<IDomainCommandHandler<FakeGenericCommand<string, string>>>()
.UsingFactoryMethod(input => new FakeGenericCommandHandler<string, string>())
.LifestyleTransient());
建议?
你在这里什么是需要一个的教科书案例类型化厂 :我回答 ,我描述了如何使用它的一个问题
这个答案在很大程度上受到启发这篇文章 。
注册您的所有处理器
container.Register(Classes.FromAssemblyInThisApplication()
.BasedOn<IDomainCommandHandler>()
.WithServiceAllInterfaces());
声明一个工厂接口,将返回的处理程序的命令
public interface IDomainCommandHandlerFactory
{
IDomainCommandHandler[] GetHandlersForCommand(IDomainCommand command);
}
您需要在命令类型链接到处理程序,您可以用自定义选择做:
public class HandlerSelector:ITypedFactoryComponentSelector
{
public TypedFactoryComponent SelectComponent(MethodInfo method, Type type, object[] arguments)
{
var message = arguments[0];
var handlerType = typeof(IDomainCommandHandler<>).MakeGenericType(message.GetType());
return new TypedFactoryComponentCollection(handlerType.MakeArrayType(), new Arguments(arguments));
}
}
然后告诉温莎你想有一个工厂,将返回IDomainCommandHandler<T>
别代码,工厂什么。
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<ITypedFactoryComponentSelector>().ImplementedBy<HandlerSelector>());
container.Register(Component.For<IDomainCommandHandlerProvider>().AsFactory());
现在,您可以使用工厂来检索您的处理程序的命令
var provider = container.Resolve<IDomainCommandHandlerFactory>();
var msg = new Type2Message();
var msgHandler = provider.GetHandlersForCommand(msg.MessageType);
请注意,本例中的处理程序没有运行对命令本身,但有一个Execute
的功能。 如果你想返回封闭的通用对象,你需要解决后投他们,因为你不能从一个方法返回不同的类型。
我建议你阅读的原创文章,因为它也包含了有关生活方式的更多信息,释放组件和其他有趣的点。
在这里,我使用其中I指定请求和作为通用部件的响应请求选择器的一个例子
protected override Type GetComponentType(MethodInfo method, object[] arguments)
{
var request = arguments[0].GetType();
var response = arguments[1] as Type;
var handlerType = typeof(IHandlerOf<,>).MakeGenericType(request, response);
return handlerType;
}
这里是该呼叫到工厂的结果(T是请求,R的响应)
var handler = handlerFactory.GetHandler<T>(input, typeof(R));
var requestType = input.GetType();
var responseType = typeof(R);
var handlerType = typeof(IHandlerOf<,>).MakeGenericType(requestType, responseType);
r = (R)handlerType.GetMethod("Handle").Invoke(handler, new object[] { input });