Aggregates, Transactional Consistency and the Entity Framework DbContext

こ雲淡風輕ζ 提交于 2019-12-18 13:34:51

问题


Aggregates must be designed to be transactionally and eventually consistency. This consistency boundary around entities helps manage complexity.

In our repository implementations, we are using Entity Framework to interface with the actual database. Historically we have always had huge contexts (spanning scores of tables) which represent every available table, field and relationship in the database (or at least in some functional area of the database). The problem here is that this context is used for hundreds of different things and grows exponentially as the system gets bigger, leading to something which is very difficult to maintain.

Division by Bounded Context

Due to this, it is often suggested that separate DbContexts should be created for each bounded context in the system. Julie Lerman proposed this in her article, Shrink EF Models with DDD Bounded Contexts.

Division by Aggregate

If our aggregates are transactionally consistent, what is stopping us from going one step further and creating dedicated contexts to serve each aggregate repository?

Instead of being promiscuous (serving everyones' needs), it would give the context clear intention.

  • The context will only ever need to change when the aggregate needs to change. It evolves with the aggregate. With larger contexts, many parts of the system could depend on one part of the context. A single change could jeopardise a lot.

  • Only the tables, fields and relationships needed by the aggregate will need to exist in the context. Often when dealing with a larger context, you aren't bothered with most of the relations or fields on a given table.

There are drawbacks with this approach. Namely:

  • Although they would likely be modeled differently (depending on their use), certain database tables and relationships may need to exist in multiple contexts.

  • If used, code-first migrations would be tricky.

  • This may be considered as over-engineering.

Can anyone provide further any insight on this approach? Is there perhaps something which I have overlooked?

EDIT:

Note that we are not using the EF data entities in our domain. Our repositories instantiate and hydrate from these data entities a richer domain model.


回答1:


I don't see multiple-aggregate Contexts as a problem, especially if you follow strict aggregate separation -- no reference to entities outside aggregate, only root-to-root loose references by key.

On the other hand, I could see why you would want atomic DbContexts if you know for sure it's a performance bottleneck.

One thing though : EF contexts don't have to map exactly to Domain layer Bounded Contexts. If they do and you try to shrink your contexts as much as possible on both sides, it could cause damage in the Domain layer IMO. The domain BC's could lose their coherence and the semantics of important ubiquitous language notions and subdivisions could be lost in the process.




回答2:


Good question - if you are using EF as CRUD access to implement a repository and then layering on top rich DDD entities, then wouldn't your bounded context dictate the size of the underlying database schema used to persist all the entities contained within?

If the underlying tables and EF context are huge, I think that would indicate the bounded context could be broken up further?

A useful link I found with EF is here: http://mehdi.me/ambient-dbcontext-in-ef6/ when I started having really complex EF schema I tried different tricks but eventually swapped them out for EventSourcing repository instead, but only where the pain of projections and infrastructure was worth getting away from migrations, table coupling etc.

Ultimately if the bounded context being modeled is correctly sized, then even if all the DbSets were contained within the same DbContext the complexity would still be manageable.

My advice is to keep everything sane and manageable by sticking with smaller bounded contexts and not share EF contexts/databases between bounded contexts.

You may find as the bounded contexts are re-factored and split there are certain parts which you can model as pure CRUD access direct to EntiyFramework using EF simply as an ORM direct to POCOs then out to your application layer.




回答3:


If our aggregates are transactionally consistent, what is stopping us from going one step further and creating dedicated contexts to serve each aggregate repository?

In my opinion this is a very bad idea. Let me give you some insights.

In Domain Driven Design you have two kind of tools; strategic and tactical. You should not divide your model based arbitrary tactical solution

Bounded Context is a strategic tool. This gives a modeling boundary in which to create a solution to the specific business problem domain. Inside a single Bounded Context is a Ubiquitous Language formulated by the team. Whitin a signel modeling boundary the team may employ any number of useful tactical modeling tools like for example Aggregates, Entities and Values Objects

So the biggest value in applying DDD is in the correct definition of Bounded Contexts. It's not just a theoretical artifact. Dividing by aggregates would lead you only to confusion and mess. You won't be able to tell what kind of domain problem you are addressing very clearly.

On the other hand you can use only tactical patterns like Aggregates, Entities and Values Objects but this is not Domain Driven Design.

Instead of being promiscuous (serving everyones' needs), it would give the context clear intention...

How ? I can't get it. For me it would creat more confusion. Bounded Context integration is done via Anti corruption layers which protect you from changes from outside. A bounded context can evolve independently of others. If you want to look more on how integration between bounded context happens from the stratgical point of view, please look to Context mapping.

Although they would likely be modeled differently (depending on their use), certain database tables and relationships may need to exist in multiple contexts. If used, code-first migrations would be tricky. This may be considered as over-engineering.

When doing Domain Driven Design you don't drive your choices based on technical constraints, especially of ORM framework.

Going further:

From time to time an aggregate can have a 1:1 mapping with Bounded Context. But this depends really on a business problem and not a technical solution.

Domain Driven Design is not easy to apply without a deeper understanding. Sometimes your domain doesn't really need it so there is no point in trying to force it to your specifics problem.

As a conclusion I would stick with the proposition that is made in Julie Lermann article.



来源:https://stackoverflow.com/questions/28658520/aggregates-transactional-consistency-and-the-entity-framework-dbcontext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!