-1

I have two bounded contexts, one to handle files and another to handled bills.

I have two projects, one for each bounded contexts.

Files can be any kind of file, an image, a document in pdf or any other format and so on.

I have a many-to-many relationship between files and bills, in the way that a bill can be related with many files and a file can be related with many bills.

I would like to add the relationship between a bill with files.

For that, I have read some examples, like Udi Dahan and stack overflow question.

But in both examples, they use a reference to the instance of the related property, instead to use only the ID how it is recommended in DDD.

In my case, if I follow the examples, first I have to choose the root entity, in my case, is the bill entity which has a collection for files. So according to the examples, I would have something like this:

public class Bill : Entity
{
    long Id;
    string Reference;
    //Another properties

    List<File> Files = new List<File>();
}

My doubt, If I am not wrong, an entity only can have reference to another instance if the instance belongs to the aggregate. But in this case, I don't think File entity belongs to the aggregate, because the file shouldn't be managed from Bill entity, to avoid modifying the file entity from a bill.

It is true that in one of the examples, the child entity, in my case File, only has the ID, so the entity would be this:

public class file : Entity
{
    long Id;
}

So I don't have the problem that I could modify the entity from Bill, I only have the ID.

But if I don't have a reference to File from Bill, how to establish the relationship in the domain? I need the reference to add the reference to the collection of files. If I only have a collection of IDs, it is not possible to stablish the relationship.

So, in summary, I would like to know if the rule to not have a reference to another entities that don't belong to the aggregate is applied when I have to set a relationship between two different root entities or not.

4
  • 1
    What behavior does File have that Bill needs to accomplish its task? I mean, are you creating a Rich Domain Model here, or a database model in disguise?
    – Rik D
    Sep 30, 2023 at 19:02
  • Just to add to Riks comment, say you substituted File for Telephone - which can have many types (Mobile, home, work) and Bill for Zebra - we still don't have a clear understanding of the relationship between the entities.
    – DavidT
    Sep 30, 2023 at 19:18
  • @RikD Bill doesn't need the file to acomplish any task, just I want to stablish a relationship between a bill and a file. But the bill doesn't need a file to pass from created to paid or some other task. But if I only should to use the file with bills if a bill needed it to acomplish a task, how could I set the relationship between the file and the bill? I need another domain for that, whick task is to create or delete a relationship between the bill and the file? Sep 30, 2023 at 19:21
  • 1
    "instead to use only the ID how it is recommended in DDD" - if you read the original DDD book, you'll find that this isn't recommended or required anywhere in it. The ID as a cross-aggregate reference is a style popularized by Vaughn Vernon; it's a way to make the aggregate boundaries more explicit in the code itself. But you don't have to do it that way, what matters is that you define the aggregate boundary. Oct 1, 2023 at 0:50

2 Answers 2

2

I think there may be a misunderstanding here what "bounded context" means. "Bounded" here means that it has boundaries, as in the semantic and physical dependencies end at the boundary.

If you need to refer to an entity in another bounded context, then by definition that is not a bounded context. Again, by definition, that entity belongs in your context, since you need it to define your stuff.

Think of a bounded context like its a separate application with its own behavior, which can run even of all other "contexts" are offline. If you can't do that, chances are you're not a bounded context.

Now, this gets tricky, when you're trying to design a system of bounded contexts to work together. The classical example being a "search" context and an "shopping cart" context. Both may have a notion of what a "Product" is, but crucially these "Products" will have vastly different behavior and data associated. They won't refer to each other. There would be no point. However, and this is where it this "refer by id" may come from, they might have the same id, and there might be some synchronization process that feed both from some third system. Note, that they both still have their own data, and can work independently of each other. The common id is just a way to link to the other domain, or communicate in some other way. It is not there to "get data" from the other domain.

To summarize: If you want to refer to an "entity" in another domain, you probably did not define your domains right. Either define the domain better, or just have them be one domain. Referring by ids won't solve this design problem at all.

1
  • When I talk about bounded context, I mean that I have a system (a bounded context) to manage files (create, update, delete and any other actions that I could do about files). And when I talk about bounded context for bills, it is to manage bills (create, update, change states...). So I could manage files if I bill is offline and I can manage bills if files are offline. Is this correct? Perhaps I misunderstood this. Sep 30, 2023 at 19:18
0

But if I don't have a reference to File from Bill, how to stablish the relationship in the domain?

There is a possible misunderstanding around the term "reference" here. You can either reference something by its identity or directly (an "object reference").

But some people seem to find it convenient to use the word "reference" as short for "object reference" - possibly because it they have in mind the object oriented concept of reference or object pointer (as opposed to value). When they say "no reference", it means "no reference to the full object", not "no reference at all".

My doubt, If I am not wrong, an entity only can have reference to another instance if the instace belongs to the aggregate.

You can totally reference an aggregate root from another root. From Vaughn Vernon's Effective Aggregate Design:

Rule: Reference Other Aggregates By Identity

Prefer references to external aggregates only by their globally unique identity, not by holding a direct object reference (or “pointer”).

The issue of referencing an entity from another Bounded Context (not Aggregate) is something different and has already been covered in a number of questions here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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