您好。在.Net的MessageDispatch场景中,我注册了所有我的命令处理程序:
builder.RegisterAssemblyTypes(commandsAssemblies)
.AsClosedTypesOf(typeof(ICommandHandler<,>))
.InstancePerRequest();
在我的messageDispatcher的OnActivating方法中,我想用这样的messageDispatcher注册commandHandlers。
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的实现方式如下:
public class ActivateCampaignHandler : CommandHandler<ActivateCampaign,MessageResult>
{
....
我的问题是Resolve不起作用。我可以看到处理程序已注册,但只有2个服务自己和ICommandHandler
如何解决所有命令处理程序?
答案 0 :(得分:1)
我可以看到3个解决方案来检索IEnumerable<ICommandHandler<,>>
。
最简单的方法是引入非通用ICommandHandler
接口:
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>();
这是我推荐的解决方案,因为使用非通用接口可能更容易。
第二个解决方案包括使您的界面协变(使用out
修饰符)以允许从TestCommandHandler
投射到ICommandHandler<ICommand, IMessageResult>
并将您的类型注册为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
实现允许这样做。
您可以查看ContravariantRegistrationSource
以了解如何制作自己的内容。