2017-02-22 17 views
1

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

домена Событие:

public static class DomainEvent 
{ 
    public static IEventDispatcher Dispatcher { get; set; } 

    public static void Raise<T>(T @event) where T : IDomainEvent 
    { 
     Dispatcher.Dispatch(@event); 
    } 

} 

SimpleInjectorEventDispatcher

public class SimpleInjectorEventDispatcher : IEventDispatcher 
{ 
    private readonly Container container; 
    public SimpleInjectorEventDispatcher(Container container) 
    { 
     this.container = container; 
    } 

    public void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : IDomainEvent 
    { 
     var handlerType = typeof(IDomainHandler<>).MakeGenericType(eventToDispatch.GetType()); 
     var handlers = this.container.GetAllInstances(handlerType); 

     foreach (dynamic handler in handlers) 
     { 
      handler.HandleEvent((dynamic)eventToDispatch); 
     } 
    } 
} 

SimpleInjector

container.Register<IEventDispatcher, SimpleInjectorEventDispatcher>(); 

IEventDispatcher грузоотправитель всегда нуль. Как я могу убедиться, что он правильно инициализирован?

ответ

1

Диспетчер IEventDispatcher всегда имеет значение null.

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

Я бы настоятельно рекомендовал вам прекратить использовать этот статический DomainEvent класс полностью. Этот дизайн внедрен в old article от Udi Dahan, но он сам отказался от идеи использования статических классов для этой цели давным-давно. В настоящее время он консультирует, как я.

Статические классы являются трудными с точки зрения проверяемости и открытости. С этой точки зрения использование инъекции зависимостей является гораздо лучшей альтернативой.

Решение этой проблемы очень просто: удалите статический класс DomainEvents со своей базы кода и введите IEventDispatcher в конструкторы потребителей, которым требуются публикации событий.

+0

Спасибо за подробный ответ! Я возьму ваш совет и поставлю статический класс. Означает ли это, что для всех моих объектов потребуется конструктор, принимающий IEventDispatcher? – Wekslie

+1

Сущности? Нет. Сущности не должны получать свои зависимости, используя инжекцию конструктора. Если вы хотите применить DDD, вы должны использовать метод Injection, то есть метод сущности, который фактически использует зависимость, должен требовать его посредством своего метода. – Steven

+0

Еще раз спасибо! Другой связанный с этим вопрос: SimpleInjectorEventDispatcher имеет поле Контейнер. Как я могу установить это поле для использования контейнера из моей SimpleInjectorConfiguration? – Wekslie