Несколько типов для SetHandlerInterface() с мембраной и контейнером ioc

Переходя к демонстрационному коду 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();

Я использую контейнер IoC, подключенный с помощью membus, и он реализует мечту, реализуя 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();

Может кто-нибудь, пожалуйста, дайте мне знать, есть ли способ обойти это, чтобы мы могли зарегистрироваться на произвольное количество типов?

2 ответа

Решение

Я боюсь, что текущая версия MemBus не может сделать это - без особой причины, заметьте. Я знаю, что имеет смысл различать события и команды, даже если базовая инфраструктура одинакова.

Единственный способ обойти это сейчас - использовать единственный интерфейс для подключения IOC к MemBus.

Если такая функция должна быть введена в MemBus, нужно подумать, как должен выглядеть механизм поиска в контейнере IOC. Вероятно, потребуется запросить все обработчики всех интерфейсов, или потребуется ввести какой-либо способ классификации / различения событий и командных "сообщений".

Я просто настроил это для подтверждения концепции, потому что я использую следующее соглашение в соответствии с рекомендациями Microsoft CQRS Journey:

Я хотел использовать API контейнера IOC (SimpleInjector), чтобы обеспечить соблюдение соглашения, поскольку оно заставляет вас делать регистрации одного или нескольких обработчиков явными в зависимости от конструкции. Теперь мой контейнер 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);
    }
Другие вопросы по тегам