I have added below a few steps to consider when modeling your application using DDD:
- Create the model by defining the entities, aggregates, and value objects, and keep iterating and refining it as you move along.
- Define invariants (condition rules) at the aggregate-root level. The invariants live inside the aggregate: in other applications, this logic can be stored in a procedure or in the application's UI.
- Entities should act as orchestrators where the business logic should be added to the value objects. It is easier to test logic in a value object.
- Aggregates should:
- enforce data consistency.
- ensure an entity is valid.
- maintain invariants.
- deleting the root should delete the entire aggregate.
- the repository should only know the aggregate root.
5. Create domain events as classes.
6. Write the domain model logic by calling into the repositories and raising events to the application.
7. When using domain events, do the persistence first, then notify the event.
Here are a few considerations to think about:
- A domain model should also be persistent ignorant and ignorant of the implementation details. Abstraction defines what is needed. Implementation defines how it is done.
- Dependency inversion should define your model dependencies.
- On the server side, the interfaces may become too big. This will violate the open-close principle (too many changes) and the interface segregation principle (too many methods you may not need). The solution is to create a read-only and read-write set of interfaces. Similar to using the CQRS design pattern.
- Use the MediatR Nuget package to publish events and decouple the classes that trigger the events from the implementation of the events' behavior. (This is a discussion for another article).
Lastly, let's add a couple of "rules" from Steve Smith and Julie Lerman's course "Domain-Driven Design Fundamentals" which inspired this article:
- Domain-Driven Design provides guidance, not rules.
- All models are wrong. Some models are useful.
I hope you have enjoyed this short reminder about a complex topic you may need to implement someday.