Leonardo
Leonardo

Reputation: 11397

DDD - Should entities create entities?

In my domain I might have a entity called User that represents a person and Tenant, an entity that represents a business.

One might think that this is a administrative user, and as such, it should be able to register new users, which in terms of code would be translated to basically 3 forms:
-adminUserInstance.CreateUser(newUserDTO);
-tenantInstance.CreateUser(newUserDTO)
-newUserInstace.SelfSave()

Being newUserInstace.SelfSave() a necessity because of self-registration, does the other two make sense? Should i keep only the self registration and turn to a model of affiliation, where the same user can be part of multiple tenants?

In broader terms: should Questions/Answers be created by Users or self created and then tied to a given User? and on even broader terms: Should entities hold the knowledge to create other (not any-others) entities or the entities should be able to create themselves and have the "requester", for example, call a domain service that will bundle them up?

Upvotes: 3

Views: 2383

Answers (2)

Constantin Galbenu
Constantin Galbenu

Reputation: 17713

Entities can be created by entities but only inside the same aggregate. So, if an aggregate creates an entity then that entity is a nested entity; it cannot be referenced outside the aggregate's boundary. You put the creation of nested entities inside the aggregate because the aggregate needs to enforce some invariants and this is a decision to make when you design your Aggregates.

On the other hand, aggregate roots (AR) are created by the client code (an Application service in most cases) but the AR enforces it's own invariants! So, in PHP code this should look like this:

//somewhere in an Application service
function createUser($id, $username, $password) 
{
     $user  = new User(); //an AR should always be new-able, i.e. with not injected dependencies

     $user->registerNew($id, $username, $password); //here the invariants are enforced

     $this->userRepository->addOrSave($user);
}

newUserInstace.SelfSave()

An aggregate does not "save" (persists) itself. That is the job of an Application service. Anyway, "save" does not seem to be from your ubiquitous language, you need a more proper name ("register"?).

Upvotes: 2

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57397

In broader terms: should Questions/Answers be created by Users or self created and then tied to a given User? and on even broader terms: Should entities hold the knowledge to create other (not any-others) entities or the entities should be able to create themselves and have the "requester", for example, call a domain service that will bundle them up?

Udi Dahan's technical guidance was that you should always get an entity, and use it to create the new entity. "Customers don’t just appear out of thin air."

That said, creating aggregate root entities is weird; not "wrong", but it deviates from the usual patterns of dispatching commands to the aggregate you are going to modify.

Upvotes: 4

Related Questions