0

关于 AutoFac、CommonServiceLocator 和 Udi 的域事件 ( http://www.udidahan.com/2009/06/14/domain-events-salvation/ )的有效解决方案,我有一个微妙的问题。我让 Autofac 在 MVC 引导程序中设置 ServiceProvider。但是有两件事让我烦恼:1)域事件是通过使用 CommonServiceLocator 的静态方法引发的。这使得单元测试变得困难,并且它还隐藏了一些我喜欢使用的 Autofac 功能。这导致我... 2)我的事件被 IEventSubsriber 消耗,其中 T 是 DomainEvent。但情况是我喜欢在一个事件上有几个订阅者。这意味着当我提出一个事件时我会得到几个订阅者。

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

但是我已经通过 AutoFac 用 MetaData 标记了这个订阅者实例:

   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。但是在 Base Entity 类上使用 DI(它会产生什么结果)我不知道有什么简单的方法。我看过 Nicklas Blumhardt 的演示,其中 AutoFac 通过 NHibernate 拦截器将 DomainEventDispatcher 注入实体,并且可以在 Up/Down 期间将事件分派到持久性。整洁的解决方案。但我使用 Entity Framework 5,也希望有一个更简单的解决方案。

期待看到一些答案或至少讨论这个话题。我认为很多人在处理这个问题时都会停下来。也许只是——“好吧,我们只为事件使用 CSL”,它们也为单元测试设定了界限。- “我们跳过事件的单元测试”。这不是问题:)

/最好的问候马格努斯

4

1 回答 1

0

您的任务归结为将您的域代码与 Autofac、CommonServiceLocator 等依赖项解耦。这是一件好事。也就是说,在您的域代码中嵌入服务定位器(域事件注册表和引发)本质上并没有错。你只需要对降低的可发现性感到平静。还有其他实现类似目标的方法(例如,普通的 .net 事件、IObservable 实体……)。订阅应该从外部进行。例如,作为创建子生命周期范围的一部分。

要考虑的另一件事是何时应该触发事件。如果您对一点延迟没意见,您可以让实体在内部收集他们的域事件,并在操作结束时向实体询问他们收集的域事件,然后将它们分派给订阅者。请注意最后一部分如何发生在应用程序层或至少在域代码之外。很大程度上取决于您要在事件订阅者中实现的目标。

因此,解耦当然是可能的,但它需要根据您的要求验证所采取的策略。实验 :)

于 2013-10-20T09:19:41.090 回答