6

这里查看演示 CQRS 代码,命令和事件处理程序分别连接如下:

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();

任何人都可以让我知道是否有任何方法可以解决这个问题,以便我们可以注册任意数量的类型?

4

2 回答 2

3

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

目前唯一的解决方法是使用单个接口将 IOC 连接到 MemBus。

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

于 2013-04-21T10:28:00.907 回答
3

我只是将其设置为概念验证,因为我根据Microsoft CQRS Journey 指南使用以下约定:

我想使用 IOC 容器的 (SimpleInjector) API 来强制执行约定,因为它强制您通过设计明确地进行单处理程序与多处理程序注册。现在,只要意外注册了同一命令的两个处理程序,我的 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);
    }
于 2014-04-07T18:14:19.403 回答