I'm building an invitation system in which admins can only invite
This flow involves two entities Invitation
and User
.
This seems to indicate that Invitations
and User
should be added to two separated aggregates.
Then the only way to implement the logic described above is to use a domain service like IInvitationService
. Am I right?
This interface could come with two methods:
public interface IInvitationService
{
Task<Result> Create(Invitation invitation, CancellationToken token);
Task<Result> Delete(Invitation invitation, CancellationToken token);
}
Finally, if I go for the service approach, I will have two possible "ways" to create invitations.
IInvitationRepository.Create()
IInvitationService.Create()
Don't you think it is confusing?
Then the only way to implement the logic described above is to use a domain service like IInvitationService. Am I right?
Something seems to be going very wrong here. In short, domain-driven-design doesn't mean that we abandon the principles of object oriented design.
Logic is normally implemented within the aggregate root that is changing. Part of the point of introducing the aggregate pattern was to make it easier to find the code responsible for making changes -- rather than having that same code scattered all over your model, you can just think about where the change of state is happening and know where to look for the code.
The aggregate root itself knows only its own state - any other information needed to perform a change is passed to it as an argument.
So I wouldn't normally expect that you need a "domain service" for the parts of the model you have described so far.
Where a domain service is likely to come into play is the case where a change to one aggregate depends on the recent state of a different aggregate. For example, if a particular change to "invitation" depends on the current state of "user", then you might pass to the invitation method responsible for computing the change a domain service that gives access to a cached copy of the user's state.
As for create... creation patterns are weird. Udi Dahan's post is a good starting point.