События в домене (стиль Udi) и попытка обойти шаблон Service Layer

У меня деликатная проблема, связанная с тем, что у меня есть рабочее решение с событиями AutoFac, CommonServiceLocator и Udi's Domain ( http://www.udidahan.com/2009/06/14/domain-events-salvation/). Я позволил Autofac установить ServiceProvider в загрузчик MVC. Но меня раздражают две вещи: 1) События домена вызываются статическим методом, который использует CommonServiceLocator. Это затрудняет юнит-тестирование, а также скрывает некоторые функции Autofac, которые мне нравятся. Это приводит меня к... 2) Мои события потребляются IEventSubsriber, где T является DomainEvent. Но сценарий таков, что мне нравится иметь несколько подписчиков на одно мероприятие. Это означает, что я получаю несколько подписчиков, когда поднимаю событие.

 IEnumerable<IEventSubscriber<T>> registeredHandlers =
                    ServiceLocator.Current.GetAllInstances<IEventSubscriber<T>>();

Но я пометил эти экземпляры подписчика метаданными через AutoFac:

   builder.RegisterType<CreateNewRevisionEvent>().AsImplementedInterfaces()
                   .WithMetadata<EventSubsriberMetadata>(x => x.For(order => order.Order, 1));

и класс метаданных:

public class EventSubsriberMetadata
    {
        public int Order { get; set; }
    }

Итак, вопрос. Я хотел бы добиться того, чтобы я мог как-то использовать Абстрактную Фабрику (не решать 1), просто переместить проблему в другое место), Фабрику Делегатов AutoFac (Func<> не очень доволен Обобщенными) или просто и просто внедрить в DomainEventDispatcher?

Меня убивает то, что я хотел бы избежать зависимостей в сборке Domain.Core. Я знаю, что у меня есть зависимость от CommonServiceLocator сегодня. Но использовать DI в классе Base Entity (то, к чему это приведет) я не знаю ни одного простого способа. Я видел демонстрацию Никласа Блумхардта, где AutoFac внедряет DomainEventDispatcher в сущности через перехватчики NHibernate и может отправлять События во время Up/Down в постоянство. Аккуратное решение. Но я использую Entity Framework 5, а также надеюсь на более простое решение.

Ждем ответа или хотя бы обсудим эту тему. Я думаю, что многие люди останавливаются, когда они подходят к этой проблеме. И, может быть, просто: "Хорошо, мы используем CSL только для событий", и они также определяют границы для модульного тестирования. - "Мы пропускаем юнит-тестирование на события". Это не проблема здесь:)

/ С наилучшими пожеланиями Магнус

1 ответ

Решение

Ваш квест сводится к отделению кода вашего домена от таких зависимостей, как Autofac, CommonServiceLocator. Это хорошая вещь. Тем не менее, нет ничего плохого в том, что в код вашего домена встроен локатор служб (реестр и повышение событий домена). Вы просто должны быть в мире со сниженной открываемостью. Существуют и другие способы достижения аналогичной цели (например, обычные.net события, объекты IObservable, ...). Подписки должны происходить извне. Например, как часть создания дочерней области действия.

Еще одна вещь, чтобы рассмотреть, когда события должны быть запущены. Если у вас все в порядке с небольшой задержкой, вы можете сделать так, чтобы сущности собирали свои доменные события внутренне, и в конце операции запросите у сущностей их собранные доменные события, отправив их тут же там подписчикам. Обратите внимание, как эта последняя часть может происходить на уровне приложения или, по крайней мере, вне кода домена. Многое зависит от того, чего вы пытаетесь достичь в рамках подписчиков мероприятия.

Таким образом, разъединение, безусловно, возможно, но оно требует проверки стратегии в соответствии с вашими требованиями. Эксперимент:)

Другие вопросы по тегам