结束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();
任何人都可以告诉我是否有任何解决方法,以便我们可以注册任意数量的类型?
答案 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);
}