2015-09-17 2 views
3

Я пытаюсь реализовать агрегатор событий, используя 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"); 
    } 
} 

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

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

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

ответ

2

Это довольно легко сделать в 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 есть даже more, чтобы помочь с реализацией EventAggregator.

Также здесь есть решение для problem similar to yours.

gist with your working example.

Смежные вопросы