I'm trying to get my head around rich domain models and how to build semantic functionality into domain entities, where the domain entities are not tightly coupled to objects that provide implementations for semantic behaviour
For example, I want to build a User
entity into my domain model, but I want it's implementation to be driven by identity framework
class User
{
public string Email { get; set; }
... All of the other IdentityUser properties...
public void DisableUser()
{
...behaviour to disable a user, most likely requires UserManager
}
public void AddToRole(Role role)
{
... most likely requires RoleManager
}
}
So now that I have a domain model that behaves according to the business rules, and is ignorant to persistence and implementation.
But how exactly are DisableUser()
and AddToRole()
supposed to work when they have no dependencies and aren't in any way coupled to UserManager
and RoleManager
?
- Generally, what am I missing?
- Should domain entities have dependencies on objects that provide behavior?
- How should I decouple my domain model from implementation providers?
A well crafted domain model should have no dependencies on any other architectural layers or services. With respect, domain model objects should be (in my case) POCOs (Plain Old CLR Objects). Services and layers such as business logic or persistence layers should then depend on these objects and return instances of them.
There are several keys to building a domain model that respects low coupling, high cohesion and persistence ignorance. In one statement, the secret to this is "write the code you wish you had".
Domain Model Example
Granted, this domain model object was written with Entity Framework in mind, but it's a far cry from the usual Entity Framework examples (which are anemic domain models by contrast). There are a few caveats that need to be considered when crafting domain model objects in this way, but Entity Framework will persist them (with a little jiggery-pokery), and you get a domain model object that defines a clean, semantic contract to layers that depend on it.