具有membus和ioc容器的SetHandlerInterface()的多个类型

时间:2013-04-20 21:15:02

标签: cqrs membus

结束demo CQRS code here命令和事件处理程序分别连接如下:

public interface CommandHandler<in T>
{
    void Handle(T command);
}

public interface EventHandler<in T>
{
    void Handle(T @event);
}

bus = BusSetup.StartWith<Conservative>()
       .Apply<FlexibleSubscribeAdapter>(a =>
       {
           a.ByInterface(typeof(IHandleEvent<>));
           a.ByInterface(typeof(IHandleCommand<>));
       })
       .Construct();

我正在使用一个与membus挂钩的IoC容器,它通过我的容器实现IEnumerable<object> GetAllInstances(Type desiredType)接口实现梦想,但是与使用这种注册方法的演示不同,我不能拆分单独命令的接口和事件:

this.Bus = BusSetup.StartWith<Conservative>()
    .Apply <IoCSupport>(c =>
        {
            c
            .SetAdapter(SimpleInjectorWiring.Instance)
            .SetHandlerInterface(typeof(CommandHandler<>))
            /*.SetHandlerInterface(typeof(EventHandler<>))*/;
            // only CommandHandler or EventHandler can be used - not both
        })
    .Construct();

任何人都可以告诉我是否有任何解决方法,以便我们可以注册任意数量的类型?

2 个答案:

答案 0 :(得分:3)

我担心当前版本的MemBus无法做到这一点 - 没有特别的原因,请注意。我知道能够区分事件和命令是有意义的,即使底层基础设施是相同的。

现在唯一的解决方法是使用单个界面将IOC挂钩到MemBus。

如果应该在MemBus中引入这样的功能,则必须考虑IOC容器中的查找机制应该如何。它可能必须请求所有接口的所有处理程序,或者某种方式来分类/区分事件和命令“消息”必须引入。

答案 1 :(得分:3)

我只是为了概念验证而设置它,因为我按照Microsoft CQRS Journey guidelines使用以下约定:

我希望使用IOC容器(SimpleInjector)API来强制执行约定,因为它会强制您single vs multi handlers registrations explicit by design。现在,我的IOC容器会在意外注册同一命令的两个处理程序时抛出异常。

为了让MemBus支持这个约定,我需要创建自己的ISetup,ISubscriptionResolver和IoCAdapter(分别从IoCSupport,IoCBasedResolver和IocAdapter的代码开始)。我还必须创建一个新的IocAdapter接口,它也支持单一的GetInstance()方法;现在,接口大致匹配System.Web.Http.Dependencies.IDependencyScope接口(GetService和GetServices)。

// Setup
return BusSetup
    .StartWith<Conservative>()
    .Apply<CommandingEventingSupport>(
        adapter =>
            {
                adapter.SetAdapter(new MemBusSimpleInjectorAdapter(container));
                adapter.SetCommandHandlerInterface(typeof(IHandleCommand<>));
                adapter.SetEventHandlerInterface(typeof(IHandleEvent<>));
                adapter.SetCommandTest(obj => obj is IDomainCommand);
            })
    .Construct();

然后解析器将命令发送到GetInstance,将事件发送到GetAllInstances ...

    // Command vs Event
    public IEnumerable<ISubscription> GetSubscriptionsFor(object message)
    {
        bool isCommand = _isCommandFunc(message);
        Type typeToCreate = isCommand
            ? _commandHandlerType 
            : _eventHandlerType;
        var handlesType = ConstructHandlesType(typeToCreate, message.GetType());
        var mi = handlesType.GetRuntimeMethods().First();
        return isCommand
                   ? new[] { mi.ConstructSubscription(_adapter.GetInstance(handlesType)) }
                   : _adapter.GetAllInstances(handlesType).Select(mi.ConstructSubscription);
    }