本文介绍了自动解析所有ICommandHandler< ICommand,IMessageResult>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在.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&lt; ICommand,IMessageResult&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-15 17:26