multiple types for SetHandlerInterface() with membus and ioc container

风流意气都作罢 提交于 2019-12-05 06:27:07

I am afraid that the current version of MemBus cannot do that - for no particular reason, mind you. I know that it makes sense to be able to distinguish between Events and Commands, even though the underlying infrastructure is the same.

The only workaround right now is to use a single interface to hook the IOC into MemBus.

If such a feature should be introduced into MemBus one has to think how the lookup mechanism into the IOC Container should look like. It would probably have to request all handlers of all interfaces, or some way to categorize / distinguish between event and command "messages" would have to be introduced.

I just set this up for a proof of concept because I use the following convention per the Microsoft CQRS Journey guidelines:

I wanted use the IOC container's (SimpleInjector) API to enforce the convention as it forces you to make single vs multi handlers registrations explicit by design. Now, my IOC container will throw an Exception anytime two handlers for the same command are accidentally registered.

To get MemBus to support this convention, I needed to create my own ISetup, ISubscriptionResolver, and IoCAdapter (starting with the code from IoCSupport, IoCBasedResolver, and IocAdapter respectively). I also had to create a new IocAdapter interface that also supports the singular GetInstance() method; now the interface roughly matches the System.Web.Http.Dependencies.IDependencyScope interface (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 the resolver dispatches commands to the GetInstance and events to 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);
    }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!