Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD - How to manage entities across bounded contexts in EF Core

I have not found concrete examples of this. I know that each bounded context has its own versions of entities and you should not share entities across contexts. But how do I manage this in relation to using an ORM like EF?

For example, below are my entities and bounded contexts they exist in:

Ingredient (entity bounded context A)

Recipe (entity bounded context b)
Ingredient (entity bounded context b)
MenuItem (aggregate bounded context b)

Now each bounded context will have its own version of ingredient. But since I have a singular DB context in EF for managing this, how exactly do I arrange this? I am using CQRS so I can trigger events if needed. My plan was to maintain a list of ids in my Recipe entity and pull in the relevant Ingredients from the database so that data is not duplicated.

But I'm not sure if my data duplication concern is valid. In my example above, imagine a business which sells ingredients but also has preset recipes (with a list of ingredients) that it can sell in a food stall.

In one context, ingredients has no relation to another entity while in another context its a child entity (in an aggregate). I can see how it should be designed (separate entities in bounded contexts) but when it comes to the DB, how is this actually setup? What if the properties/domain knowledge that need to be tracked in context A vs context B for ingredients is different? Will this end up being a separate table? I'm a bit lost on this.

Edit: Please keep in mind I'm only using 1 database here. I understand that usually you have separate DB per bounded context to avoid this scenario but was wondering how this can be accomplished via 1 DB.

like image 765
Help123 Avatar asked Mar 01 '20 22:03

Help123


People also ask

What is a way to handle relationships between bounded contexts?

Relationships between bounded contexts pose the problem of how the development of one context influences the other over time. The safest way of dealing with related contexts is by creating an anticorruption layer (ACL).

Can a domain have multiple bounded contexts?

Anything that shows domain concepts, relationships, rules, and so on. Since a bounded context is a boundary for a model, it could include concepts from multiple subdomains. Or a single subdomain could be modelled as multiple bounded contexts.

Can a bounded context have multiple Microservices?

In general, the functionality in a microservice should not span more than one bounded context. By definition, a bounded context marks the boundary of a particular domain model.


2 Answers

I would separate your question in two parts:

  1. An architectural part: Bounded context design/boundaries
  2. A technological part: Database schema management, EF mapping, etc

From point 1, I would stress that the Bounded Context boundaries are thicker than what you imply in your question. If boundaries are well defined, there is little data duplication between BCs, a part from some Ids and little more. In your case, the ingredients in BC-A have the same Ids than the ingredients in BC-B.

For example, your BC-A might manage the name, description, pictures and so on from the ingredients. BC-B does not need this information, but instead, it might have some important properties required in order to create the recipes. In a similar way, a BC-C might have the providers, prices and so on of every ingredient.

Also, in your BC-B, you might have the ingredients in two places: A table with all the ingredients and their interesting properties for the recipes and as Entities as part of a Recipe. This entity wouldn't have all those properties, instead it would have the Ingredient Id plus the quantity used in that recipe, for example.

With this type of set up, it's not only non desirable in principle, but even in practice, to share the Ingredients tables across Bounded Contexts.

Many times, the need from data duplication comes from UI needs. For example, you will need to show the Ingredient's names when you show Recipes, but this can be solved by UI composition. The UI can pull the recipes from BC-B and enrich the data with the names in BC-A and maybe with the prices in BC-C.

If you follow this approach, point 2 should fall on its own: every BC should have its own DbContext. It is OK to use the same connection string (database) for all DbContext, but you can initialize the DbContext with specific DB schema. This way, you can have an Ingredients table in each BC without DB table conflicts and you can have EF migrations versions tables per DbContext as well (although I believe it also works with a shared table). This set up also gives you the advantage of allowing you to separate the databases in a single DB per Bounded Context without having to change any code. You might need this eventually for scalability reasons, or to facilitate infrastructure as code, etc.

like image 50
Francesc Castells Avatar answered Oct 05 '22 18:10

Francesc Castells


TL/DR: having a single db service is perfectly OK (for smaller services or due to some bussiness specific reason), so long as the data aren't shared. If you use a normal form db, use different tables to store your two ingredients.

Longer version:

If your ingredient entities in those two bounded contexts are backed by the same physical table, and moreover they can share data (one Ingredient entity can operate on data created by the other ingredient entity), then they're not really independent.

One very important aspect of having BC as a boundary, is to exactly allow those entities to evolve independently. By having them share a table (or document collection), you don't allow for that to happen. Moreover, this is violating the more generic (I mean non-DDD specific) guideline of "you shouldn't share a db across service boundaries".

like image 36
Savvas Kleanthous Avatar answered Oct 05 '22 19:10

Savvas Kleanthous