【发布时间】:2019-11-10 17:32:18
【问题描述】:
我读到人们在他们的领域驱动设计中使用事件调度库来处理领域事件。
C# 语言使用 event 关键字和 EventHandler<> 类内置了对 events 的支持。用它代替事件调度库(如MediatR)是否可行?
我知道域事件通常在持久化时调度,而不是在调用聚合上的方法时调度。但是通过将事件添加到List<Action>,您可以推迟事件的引发。
事件声明:
public event EventHandler<InvoiceCreatedEventArgs> InvoiceCreated;
延迟事件引发:
private ICollection<Action> _events = new List<Action>();
public void AddDomainEvent(Action action)
{
_events.Add(action);
}
protected virtual void OnInvoiceCreated(InvoiceCreatedEventArgs e)
{
AddDomainEvent(() => { InvoiceCreated?.Invoke(this, e); });
}
如果事件作为根聚合的公共成员公开,那么每当从存储库中获取根聚合时,应用程序都必须重新订阅根聚合的每个新实例。
对于每个实例都必须重新订阅,这不是有点不受欢迎吗?应用程序是否也必须取消订阅?
除非事件被声明为static,但我听说过关于静态事件和内存泄漏的坏消息。这会是一个问题吗?
如果使用 C# 事件,它们是属于根聚合还是属于存储库?
如果事件是在存储库中声明的(可以是 Entity Framework Core DbContext),那么当使用 .AddDbContext 方法向 ASP.NET Core 依赖处理程序注册时,它将使用“Scoped " 生命周期(每个客户端请求一次),因此除非将事件声明为静态,否则应用程序必须重新订阅每个新传入的 HTTP 请求都会发生的存储库的每个新实例。
在采用域驱动设计的应用程序中将 C# 事件用于域事件是否可行,或者它只是一个不可行的命运多舛的想法?
【问题讨论】:
标签: c# events domain-driven-design eventhandler