avatarCharles

Summary

The provided content discusses implementing domain events in .NET Core using the MediatR library to facilitate in-process communication between domain entities and maintain a clean domain-driven design (DDD) architecture.

Abstract

Domain events in .NET Core are a mechanism to allow different parts of a domain to remain decoupled yet informed about significant changes or actions within the domain. The use of the MediatR library is recommended for dispatching these events, as it provides a simple and dependency-free way to handle in-process messaging. MediatR supports request/response, commands, queries, notifications, and events, aligning with the Command Query Responsibility Segregation (CQRS) pattern and the mediator pattern. The content illustrates how to add domain events to a student entity, showing how a student enrolling in a course triggers a domain event that is then handled by a corresponding event handler in the application layer. The infrastructure layer is responsible for dispatching these events to their handlers before persisting changes to the database, ensuring that side effects are managed within the domain. The article also promotes a full course on Udemy for a comprehensive understanding of DDD, CQRS, and using MediatR for domain events in .NET Core.

Opinions

  • The author suggests that domain events are crucial for maintaining a clean DDD architecture, preventing tight coupling between entities like Student and Todo.
  • MediatR is presented as a preferred tool for implementing the mediator pattern in .NET Core, due to its simplicity and support for various messaging patterns.
  • The article implies that using MediatR to handle domain events is an effective way to adhere to the principles of CQRS within a DDD application.
  • It is implied that separating the dispatching of domain events to the infrastructure layer, just before saving changes to the database, is a best practice in DDD.
  • The author encourages readers to seek further education on the topic through a recommended Udemy course, suggesting that the article's content is a starting point for a deeper dive into DDD practices.

Domain Events in .Net Core using the MediatR Library

What are domain events?

Domain events are used to communicate with other entities or aggregates. Use domain events when something happens in the domain that different parts of the domain should be aware of. In DDD, side effects occur within the same domain.

For example, if you have a student entity and you want a student to add a todo, you would end up adding the code to the student entity that calls the Todo entity class, which is not good practice in DDD. Todo is an entity, and Student is also an entity; they should only manage its state and communicate by adding domain events and using a mediator object.

Domain-event communication happens in-process. A mediator object is used in-between to communicate with other entities. We use the MediatR library to dispatch domain events.

DDD communication with domain events

What is MediatR?

MediatR is a simple, unambitious mediator implementation in .Net It supports in-process messaging with no dependencies.

It also supports request/response, commands, queries, notifications, and events, synchronous and async, with intelligent dispatching via C# generic variance.

The MediatR is built to support CQRS, which stands for Command Query Responsibility Segregation, which defines a way to structure your read and write database operations, and it also supports the mediator pattern.

We can use the MediatR library to create the mediator pattern in your code. It is a class that communicates with another class or some classes by using the MediatR mediator object.

In MediatR, we can send an in-process message (messages are handled in-process) in a request/response style that is handled by a single handler.

You can also publish messages to multiple handlers by using the INotification and INotificationHandler interfaces.

Install MediatR from the NuGet package manager

Adding Domain Events

In the student entity, we define a behavior that enables a student to enroll in a course. In the image below, you will notice the AdddomainEvent() method that adds the courseEnrolledDomainEvent object. Anytime a student enrolls in a course, a default to-do is created for a task the student needs to do.

Student Entity Course Enrollment Behavior

The AddDomainEvent code is defined in the Entity base class that all aggregate root or entities inherit. The entity class is where the ID primary key gets defined in the domain layer. The AddDomainEvent method just adds a list of INotification to a list collection.

The Base Entity Class

The Domain Event Handler

The domain event handler defines a handler for a notification. Every domain event should have its own domain event handler. Whenever a domain event is added, the MediatR is responsible for dispatching the domain event to its handler.

The domain event handler can be defined in the application layer.

The Domain Event Handler For Course Enrollment

Now the question is, where do we add the dispatching code using the MediatR library?

Dispatching Domain Events Using MediatR

In the infrastructure layer, we define code that dispatches the domain events to their own handlers. This should be done right before SaveChanges() is called in the DbContext class.

The MediatorExtension

The DispatchDomainEventsAsync method defines code that dispatches the domain event to its handler. The code gets all domain events added to the collection, iterates through them, and publishes the domain event before changes are saved in the database.

await mediator.Publish(domainEvent)

Dispatch before SaveChanges()

That's all for adding domain events using the MediatR library. To get the full course on Domain Driven Design, including how to layer a DDD application, use CQRS and Domain Events with MediatR, and structure your entities to follow DDD, enroll for the discounted course at Udemy

Domain Driven Design
Net Core
Software Architecture
Software Development
Recommended from ReadMedium