I read that people use event dispatching libraries for domain events in their domain-driven design.
The C# language have built-in support for events using the event
keyword together with the EventHandler<>
class. Is it feasible to use this instead of a event dispatcher library (such as MediatR)?
I know that domain events are often dispatched when persisted, not when the method on the aggregate is called. But by adding the events to a List<Action>
you can defer the raising of events.
Event declaration:
public event EventHandler<InvoiceCreatedEventArgs> InvoiceCreated;
Deferred event raising:
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); });
}
If the events are exposed as public members of the root aggregate then the application would have to resubscribe for every new instance of the root aggregate whenever a root aggregate was fetched from the repository.
Wouldn't that be a bit of a undesirable trait to have to resubscribe for every instance? Would the application have to unsubscribe too?
Unless the events were declared as static
, but I have heard bad things about static events and memory leaks. Would this be a concern?
If C# events were used, would they belong in the root aggregate or would they belong in the repository?
If the events were declared in the repository (which could be a Entity Framework Core DbContext
) then when registered with the ASP.NET Core dependency handler using the .AddDbContext
method it would be registered with the "Scoped" lifetime (once per client request), so unless the events were to be declared as static then the application would have to resubscribe on every new instance of the repository which would occur at every new incoming HTTP request.
Is using C# events for domain events in a application employing domain-driven design feasible or is it just an non-viable ill-fated idea?