问题描述
在.Net的MessageDispatch方案中,我注册了所有的命令处理程序,如下所示:
Hi In a MessageDispatch Scenario in .Net i register all my command handlers like this:
builder.RegisterAssemblyTypes(commandsAssemblies)
.AsClosedTypesOf(typeof(ICommandHandler<,>))
.InstancePerRequest();
在我的messageDispatcher的OnActivating方法中,我想这样向messageDispatcher注册commandHandlers.
in my OnActivating method for my messageDispatcher i want to register the commandHandlers with the messageDispatcher like this.
builder.RegisterType<MessageDispatcher>()
.As<IMessageDispatcher>().InstancePerRequest()
.OnActivating(e =>
{
var handlers = e.Context.Resolve(IEnumerable<ICommandHandler<ICommand,IMessageResult>>);
foreach (var handler in handlers)
{
e.Instance.RegisterCommandHandler(handler);
}
......
commandHandler的实现方式如下:
A commandHandler is implemented like:
public class ActivateCampaignHandler : CommandHandler<ActivateCampaign,MessageResult>
{
....
我的问题是解决无法正常工作.我可以确定该处理程序已注册,但它自身和ICommandHandler仅有2个服务
My problem is that the Resolve doesnt work. I Can se that the handler is registered, but only has 2 services it self and ICommandHandler
如何解决所有命令处理程序?
How do I resolve all my commandhandlers?
推荐答案
我可以看到3种解决方案来检索IEnumerable<ICommandHandler<,>>
.
I can see 3 solutions to retrieve a IEnumerable<ICommandHandler<,>>
.
最简单的方法是引入一个非通用的ICommandHandler
接口:
The easiest one would be to introduce a non generic ICommandHandler
interface :
public interface ICommandHandler { }
public interface ICommandHandler<TCommand, TMessageResult>
: ICommandHandler
where TCommand : ICommand
where TMessageResult : IMessageResult
{ }
// register it this way
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.AsClosedTypesOf(typeof(ICommandHandler<,>))
.As<ICommandHandler>();
这是我推荐的解决方案,因为使用非通用接口可能会更容易.
This is the solution I recommend because it may be easier to work with a non generic interface.
第二种解决方案是使接口协变(使用out
修饰符)以允许从TestCommandHandler
强制转换为ICommandHandler<ICommand, IMessageResult>
并将类型注册为ICommandHandler<ICommand, IMessageResult>
The second solution would consist of making your interface covariant (using the out
modifier) to allow casting from TestCommandHandler
to ICommandHandler<ICommand, IMessageResult>
and register your types as ICommandHandler<ICommand, IMessageResult>
public interface ICommandHandler<out TCommand, out TMessageResult>
where TCommand : ICommand
where TMessageResult : IMessageResult
{ }
// register this way
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.AsClosedTypesOf(typeof(ICommandHandler<,>))
.As<ICommandHandler<ICommand, IMessageResult>>();
// resolve this ways
var commandHandlers = container.Resolve<IEnumerable<ICommandHandler<ICommand, IMessageResult>>>();
Console.WriteLine(commandHandlers.Count());
最新的解决方案是创建自己的IRegistrationSource
,这需要更多的工作,但是它将避免将您的类型注册为ICommandHandler<ICommand, IMessageResult>
,并允许您解析诸如ICommandHandler<ISpecificCommand, IMessageResult>
之类的内容(如果您执行IRegistrationSource
当然).
The latest solution would be to create your own IRegistrationSource
it requires more work but it will avoid registering your types as ICommandHandler<ICommand, IMessageResult>
and will allow you to resolve things like that ICommandHandler<ISpecificCommand, IMessageResult>
(if you IRegistrationSource
implementation allows that of course).
您可以查看 ContravariantRegistrationSource
来了解如何制作自己的产品.
You can have a look at the ContravariantRegistrationSource
to see how to make yours.
这篇关于自动解析所有ICommandHandler< ICommand,IMessageResult>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!