Closed razvan-tache closed 4 years ago
My suggestion is to start by modeling your domain, then jump into your application layer and finally the read model.
I use to do the following exercise when modeling aggregates:
Let's say User
can't live without Profile
. That converts Profile
in your aggregate root and user into his child. The how to is here in broadway examples.
That said, you only need here a ProfileRepository
as is the entity in charge of all the aggregates (because is the aggregate root). How you model here your Domain Events is up to you. keep in mind that child entities should fire is own events so you should not raise a User specific event from Profile.
Let's do it with examples:
Let's asume Profile and User are a 1-1 relation. Means there's no sense to fire a ProfileWasCreated and UserWasCreated event at the same time as you're firing two events for the same action.
Profile::create()
-> fires a ProfileWasCreated
event
Now asume password lives in
User
entity
Profile::changePassword()
-> call $this->user->changePasword()
-> And is thisUser
function who fires UserPasswordWasChanged
event as Profile just acts as proxy entity here.
Knowing the dependencies we know already that we need our ProfileRepository in the command handler to check for possible duplicates (idempotency) and for persistence.
In your EventBus a ProfileWasCreated
event is now published. Use a Subscriber to get this event and model your read model as you want. Here you can have a UserRepository, ProfileRepository, it really depends of your needs.
This repo has a branch example-relations
you can look for references and some pro tips to avoid extra queries like this one of createReference
in the ProjectionFactory aka event subscriber
Thanks for the fast answer. This makes a lot of sense. I will look over the examples!
I'll close the issue. Feel free to reopen if needed. I'll also think about add this to the documentation
If you would have an entity, let's say Profile, that contains an User. How should the createProfile use case look? It should use the UserRepository and ProfileRepository? Fetch the user, and then create a profile for that User? Or should the bus be used?