【问题标题】:multiple types for SetHandlerInterface() with membus and ioc container带有 membus 和 ioc 容器的 SetHandlerInterface() 的多种类型
【发布时间】:2014-04-08 02:33:58
【问题描述】:

通过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&lt;object&gt; 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();

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

【问题讨论】:

    标签: cqrs membus


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      我只是将其设置为概念验证,因为我根据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);
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-11
        • 1970-01-01
        • 2011-04-29
        • 2011-07-01
        • 1970-01-01
        • 2022-11-10
        相关资源
        最近更新 更多