Агрегатор событий DryIOC

Я пытаюсь реализовать агрегатор событий с помощью DryIOC. У меня есть диспетчер событий:

public class DryIocEventDispatcher : IEventDispatcher
{
    private readonly IContainer _container;

    public DryIocEventDispatcher(IContainer container)
    {
        _container = container;
    }

    public void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : EventArgs
    {
        foreach (var handler in _container.ResolveMany<IHandles<TEvent>>())
        {
            handler.Handle(eventToDispatch);
        }
    }
}

У меня есть несколько классов, которые могут обрабатывать события. Обозначается следующим интерфейсом:

public interface IHandles<T> where T : System.EventArgs
{
    void Handle(T args);
}

Суть в том, что когда я вызываю метод диспетчеризации диспетчера событий и передаю тип, наследуемый от EventArgs. Он берет из контейнера IOC все типы, реализующие IHandles ‹>, и вызывает для них метод handle.

Тип события может обрабатываться несколькими Сервисами. А служба может обрабатывать несколько типов событий. например:

public class ScoringService : IHandles<ZoneDestroyedEventArgs>, IHandles<ZoneCreatedEventArgs>
{
    public void Handle(ZoneDestroyedEventArgs args)
    {
        Console.WriteLine("Scoring Service Handled ZoneDestroyed Event");
    }

    public void Handle(ZoneCreatedEventArgs args)
    {
        Console.WriteLine("Scoring Service Handled ZoneCreated Event");
    }
}

public class RenderingService : IHandles<ZoneDestroyedEventArgs>, IHandles<ZoneCreatedEventArgs>
{
    public void Handle(ZoneDestroyedEventArgs args)
    {
        Console.WriteLine("Rendering Service Handled ZoneDestroyed Event");
    }

    public void Handle(ZoneCreatedEventArgs args)
    {
        Console.WriteLine("Rendering Service Handled ZoneCreated Event");
    }
}

Службы должны делать другие вещи, а также обрабатывать события (но могут не иметь других интерфейсов, поскольку они не требуются). Некоторые службы должны быть одноэлементными, а обработка событий должна учитывать регистрацию одноэлементов. Таким образом, вызов container.Resolve (IHandles ‹>) должен возвращать тип Singleton для этой службы, а не создавать несколько экземпляров. Эти службы собирают события из нескольких источников и, следовательно, должны поддерживать внутреннее состояние, прежде чем отправлять их в другое место. Поэтому разные обработчики событий, вызывающие разные службы, должны быть отправлены в один и тот же базовый экземпляр.

Я хотел бы иметь возможность добавлять интерфейсы IHandles к любой службе и получать ее автоматически, без необходимости каждый раз возиться с сопоставлениями IOC. В идеале типы услуг следует добавлять также с использованием сопоставления на основе соглашений.

Пока работаю над этим два дня. Я отказался от попыток добиться этого с помощью карты структуры. Сейчас я пробую DryIOC, но мне еще труднее понять и исправить.


person reach4thelasers    schedule 17.09.2015    source источник


Ответы (1)


Это довольно просто сделать в DryIoc (я владелец). Здесь я расскажу о версии V2 RC.

Учитывая, что вы заменили IContainer зависимость на IResolver, которая вводится автоматически:

var container = new Container();

container.Register<IEventDispatcher, DryIocEventDispatcher>();
container.RegisterMany<ScoringService>(Reuse.Singleton);
container.RegisterMany<RenderingService>();

var eventDispatcher = container.Resolve<IEventDispatcher>();

eventDispatcher.Dispatch(new ZoneDestroyedEventArgs());
eventDispatcher.Dispatch(new ZoneCreatedEventArgs());

RegisterMany позаботится о том, чтобы обработчики повторно использовались как Singleton и вернет один и тот же экземпляр для обоих Handles<> интерфейсов.

Кроме того, вы можете использовать RegisterMapping, чтобы добавить / сопоставить службу IHandles<> уже зарегистрированная реализация.

DryIoc имеет даже больше, чтобы помочь с реализацией EventAggregator.

Также здесь есть решение для проблема, похожая на вашу.

суть вашего рабочего примера.

person dadhi    schedule 17.09.2015