-1

I am new to event sourcing and ddd and trying to create a simple app to learn more, but I'm strruggling with how to model a relationship between two aggregates.

The idea is to allow companies to create activities that can then be searched for by users.

I want to be able to enforce the rule that a company can only have so many active activities depending on thier membership level.

My first approach would be to have the Company be the aggregate root which would contain the list of Activities and easily control this. However, this means I would have to go through the Comapny Aggregate to access every Activity, which hisn't ideal as most actions against an activity does not depend on the Company.

My second approach was to have seperate Company and Activity aggreagtes. This means that I would have to first raise a ActivityCreated event, then an ActivityAddedToCompany event which would throw an exception if the company is already full of Activities. This approach seems better but I'm not sure if needing the ActivityAddedToCompany is a flag that I have not seperated the aggregates correctly as in a happy path, the ActivityCreated and ActivityAddedToCompany would always be stored after each other.

Is the second approach better or am I missing something basic in Domain Driven Design?

  • To help clarify, I would suggest sticking to the term Activity. You sometimes call these events and sometimes Activities. You also use Business and Company interchangeably, which is not so egregious, but adds to the confusion. Defining and sticking to a Ubiquitous Language is helpful in removing ambiguities. Secondly, could you specify whether an Activity can exist without a Company? Can multiple Companies share the same Activity? – CPerson Sep 25 '19 at 12:40
  • Thanks, for your reply. I am still working everything out naming wise but have editted my question to use Activity and Company as you suggest. The rules are that an Activity does not have to be created by a Company. And lets say that a Company can only have 5 Activities at any one time (the Activities will be 'removed' once they have happended). An Activiy can only be registered to one Company. – Robert Harvey Sep 25 '19 at 17:54

1 Answers1

0

As per your clarifications:

an Activity does not have to be created by a Company

This suggests that Activity should be an aggregate of its own. It has a lifetime separate from any other aggregate.

An Activity can only be registered to one Company

The Activity would have a reference back to the Company via an ID. Effectively, a foreign key. When it is assigned to a Company, it raises an event indicating that the assignment was made.

a Company can only have 5 Activities at any one time

If you were using a standard RDBMS system to manage these rules, you would have a transaction that checks the number of Activities and either approves or rejects the addition of a new Activity. Similarly, in your domain, you can model this through a two-phase commit.

When you assign an Activity to a Company (AssignToCompany command), you raise an AssignedToCompany event. A ProcessManager (PM) will receive that event and send a command to Company (AssignToActivity) and the Company can either accept (AssignedToActivity) or reject that based on the count (RejectedAssignToActivity).

If the latter, the PM will receive the RejectedAssignToActivity event and send a command back to Activity to remove the company (UnassignCompany) which will raise the CompanyUnassigned event.

Optional:

The PM will receive the CompanyUnassigned event and send an UnassignFromActivity command to the Company. This way, you can unassign an activity if needed and have the Company be aware of the change.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
CPerson
  • 1,222
  • 1
  • 6
  • 16
  • Thanks for your answer and help in the comment, that seems like a better solution. I'll try to implement this and look more into Process managers. Thanks. – Robert Harvey Sep 27 '19 at 20:08
  • @RobertHarvey I didn't pick the best names (how ironic), but hopefully it was clear enough. – CPerson Sep 27 '19 at 20:45