Multiple types for SetHandlerInterface () with membus and ioc container

Passing the CQRS demo code here , the command and event handlers are connected separately, as shown below:

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

I use an IoC container connected to membus, and it dreams of implementing the IEnumerable<object> GetAllInstances(Type desiredType) with my container, however, unlike the demonstration using this registration method, I cannot separate the interfaces for the individual commands and events:

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

Can someone please tell me if there is a way around this so that we can register for an arbitrary number of types?

+6
source share
2 answers

I am afraid that the current version of MemBus cannot do this - for no particular reason, mind you. I know that it makes sense to distinguish between events and teams, although the underlying infrastructure is the same.

The only workaround now is to use a single interface to connect IOC to MemBus.

If such a function should be introduced in MemBus, you need to think about what the search mechanism in the IOC container should look like. You will probably need to request all the handlers for all interfaces, or some way to classify / distinguish events and β€œmessage” commands should be entered.

+3
source

I just installed this to prove the concept, because I use the following convention in the Microsoft CQRS Journey Guidelines :

I wanted to use the IOC container API (SimpleInjector) to enforce the agreement, because it forces you to do single or multiple registration registrations by design . Now my IOC container will throw an exception at any time when there are two handlers for the same command accidentally registered.

For MemBus to support this convention, I needed to create my own ISetup, ISubscriptionResolver and IoCAdapter (starting with the code IoCSupport, IoCBasedResolver and IocAdapter, respectively). I also had to create a new IocAdapter interface that also supports a single GetInstance () method; the interface now roughly corresponds to the System.Web.Http.Dependencies.ID interface of the Scope dependency (GetService and 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(); 

And then resolver sends GetInstance commands and GetAllInstances events ...

  // 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); } 
+3
source

All Articles