-1

This is my specific situation:

I am following DDD and Event sourcing to implement my application (using C#). I have a Domain layer that contains Aggregates' implementation. I write unit tests for this layer to cover my business logic.

Consider Employee aggregate that contains a field which is named PartyId. I have a specification that says, If the Party doesn't exist, I will receive an error with code 'NotFoundParty-01'.

For more details, Party is defined in another Bounded Context and Its Id will be used in Employee. I am having two different kinds of databases. one for reading(projection) and another for writing(event-store).

Now, I have a general question. Checking this kind of existence is the Domain concern or any other layers? According to the specification, this logic should be in the Domain layer or it can be on the others too?

Is it possible that the analysis guy thought in a technical way? because existing of an Aggregate is not that much business-related.

4
  • If you have a BC specifically to handle parties, why not handle adding employees to parties in that context? There, in order to prevent the same situation, duplicate employees in that BC, but only parts of an employee that are relevant in that context. The name doesn’t even have to be employee, it could be participant or whatever makes sense for that BC.
    – Rik D
    Jan 29 at 10:59
  • Because Employee doesn't mean in the Party's BC. The employee that I am working on is in HRM BC. On the other hand, I can't understand duplication relation with existence? My question was about how to be sure about the existence of an aggregate during creation or modification? Would you explain how the participant is going to handle this concern? @RikD
    – Mehrdad
    Jan 29 at 11:06
  • 1
    Why does the HRM context needs to know anything about Party? Wouldn’t it make more sense if the Party BC has its own domain concept of participants, members, party people of whatever you want to call them? If not, and party is a concern purely for employees, why is it in a separate BC? Imo referencing concepts with Ids from other BC is a sign of incorrect boundaries.
    – Rik D
    Jan 29 at 14:27
  • @RikD I agree with you about 'Why does the HRM context need to know anything about Party'.
    – Mehrdad
    Feb 5 at 10:54

1 Answer 1

0

Checking this kind of existence is the Domain concern or any other layers? According to the specification, this logic should be in the Domain layer or it can be on the others too?

Retrieving the information is an application concern; deciding what to do with the information is a domain concern.

There are a number of different designs you might choose to bridge the gap between these concerns. They have different tradeoffs.

Beyond Mock Objects by J. B. Rainsberger is a pretty good introduction.

Consider:

def someLogic(partyId, service):
  if (service.exists(partyId)):
    // logic logic logic
  else:
    error(NotFoundParty-01)

We can trivially refactor this like so:

def someLogic(partyId, service):
  partyExists = service.exists(partyId)

  if (partyExists):
    // logic logic logic
  else:
    error(NotFoundParty-01)

and then like so:

def someLogic(partyId, service):
  partyExists = service.exists(partyId)
  return pureDomainLogic(partyExists)

def pureDomainLogic(partyExists):
  if (partyExists):
    // logic logic logic
  else:
    error(NotFoundParty-01)

Please notice that

  • pureDomainLogic is now really easy to test in isolation
  • someLogic is now "so simple there are obviously no deficiencies"

Now, focusing our attention on the newly refactored someLogic piece, we can ask - do we want that code in the application layer or in the domain layer?

Either answer can be "right" - they have different tradeoffs. If you always need partyExists (or equivalently, if you always want that lookup to happen, regardless of whether you need the value in this work), then retrieving the code in the application layer simplifies your domain code. On the other hand, if you only want that value sometimes... passing the capability to the domain model may be easier than designing the protocol that tells the application layer when the query is required.

2
  • Bringing someLogic into the domain model leads to an impure / unisolated domain model. The model can no longer function on its own, but has an out-of-process dependency (yes, even via interface or delegation).
    – Rik D
    Jan 30 at 18:01
  • Also note that reaching out to another BC to check some state doesn’t give much guarantees; the partyId can exist when the command is executed and be deleted one second later.
    – Rik D
    Jan 30 at 18:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.