我们正在开发一个新项目(重写现有应用程序),我的域模型/存储库设计遇到了问题。
这是我们的域模型中两个关键部分的(简化)版本:
如您所见,我有一个帖子的抽象概念,可以是评论、讨论、照片、视频等。帖子还可以有评论。
我还有一个位置的抽象概念,显然是街道、城市、社区等。
现在,这在我看来自然是两个清晰的聚合根。
因此,我创建了两个存储库,一个名为 PostRepository,另一个名为 LocationRepository。
这一切都工作正常,我可以添加/获取任何类型的帖子(或评论),并通过这两个存储库之一添加/获取任何类型的位置。
但现在我处于一个城市的“登陆页面”的场景中(例如)。
在此页面上,我基本上需要显示“该位置的所有帖子”。
这是如何定义的?嗯,可以(可选)在某个位置标记帖子。实现细节,所以我不想太深入地研究数据(因为这不是 DDD 的目的),但本质上有地理空间智能来通过位置的形状文件来计算出哪些帖子包含在特定位置,以及标记帖子的纬度/经度。
但如何才能在不跨越边界的情况下检索这些信息呢?
我使用哪个存储库?我需要一个新的吗?
如果重要的话(或者出于好奇),这是一个 Web 应用程序 (ASP.NET MVC),带有 SQL Server 2008 数据库和 Entity Framework 4.0。
如果您需要任何说明,请告诉我。
编辑
我们当前使用规范模式的修改版本来检索域模型。
例如,这是我们 BLL 中检索所有 Review 的代码,其中 Score >= 4:
var reviews = postRepository // GenericRepository<Post>
.Find() // IQueryable<Post>
.OfType<Review>() // IQueryable<Review>
.Where(x => x.Score >= 4)
.ToList(); // List<Review>
但现在我需要一些这样的代码:
var reviews = postRepository
.Find()
.OfType<Review>()
.Where( //lat long, or Locations FK )
.ToList();
问题是我不知道如何在不添加中间连接的情况下执行上述查询 -实体(LocationPost - 因为它是多对多),并将 FK 添加到 Post 域模型中。
但这样做,我就跨越了总体界限——不是吗?
We're working on a new project (re-writing existing app), and I'm running into problems with my domain model / repository design.
Here is a (simplified) version of two key portions in our domain model:
As you can see, I have an abstract concept of a Post, which can be things like a Review, a Discussion, a Photo, a Video, etc. Posts can also have comments.
I also have a abstract concept of a Location, which are obviously things like Streets, Cities, Neighbourhoods, etc.
Now, this naturally looked to me as two clear aggregate roots.
So I created two repositories, one called PostRepository, and another called LocationRepository.
This was all working fine, I can add/get any type of Post (or comment), and add/get any type of Location via one of these two repositories.
But now im in the scenario of a "landing page" for a City (for example).
On this page, I need to basically show "all posts for this location".
How is that defined? Well, a Post can be (optionally) tagged at a Location. Implementation detail, so I don't want to go too deep into data (as that's not what DDD is about), but essentially there is geospatial intelligence to work out which posts are contained in a particular location by the shape file of the location, and the latitude/longitude of the tagged Post.
But how can I retrieve this information without crossing the boundaries?
Which repository do I use? Do I need a new one?
If it matters (or for the curious), this is a web application (ASP.NET MVC), with a SQL Server 2008 database and Entity Framework 4.0.
If you need any clarification, let me know.
EDIT
We currently use a modified version of the Specification pattern in order to retrieve domain models.
For example, this is the code in our BLL to retrieve all Review's where Score >= 4:
var reviews = postRepository // GenericRepository<Post>
.Find() // IQueryable<Post>
.OfType<Review>() // IQueryable<Review>
.Where(x => x.Score >= 4)
.ToList(); // List<Review>
But now I need some code like this:
var reviews = postRepository
.Find()
.OfType<Review>()
.Where( //lat long, or Locations FK )
.ToList();
The problem is I don't know how to do the above query without adding an intermediary join-entity (LocationPost - as it's a many to many), and add a FK to the Post domain model to that.
But by doing that, I am crossing the aggregate boundaries - aren't I?
发布评论
评论(3)
为什么这是一个问题?
根据埃文斯在他的书中的说法,一个 AR 很可能引用另一个 AR。
(但是,您不能从另一个 AR 引用一个 AR 中的子元素)
此外,位置真的是聚合根吗?
聚合根的定义是它充当一致性的边界。
这符合位置的定义吗?
我想说位置是一个值对象。
关于存储库和 AR 关联,这里几乎有两个阵营:
一种认为所有聚合根必须通过各自的存储库获取,并且 AR 应该使用软关系,例如它们之间的 ID
,另一种认为说聚合根可以很好地获取其他相关的聚合根,并且存储库只是查找聚合根的一种方式。
Why is this a problem?
According to Evans in his book, one AR may very well reference another AR.
(You may not however reference a child element in an AR from another AR)
Also, are locations really aggregate roots?
The definition of an aggregate root is that it acts as a boundary of concistency.
Does that fit the definition of a location?
I'd say a location is a value object.
There are pretty much two camps here regarding repositories and AR associations:
One that says that all aggregate roots have to be fetched through their respective repository, and AR's should use soft relations, eg ID's between them
And one that says that aggregate roots may very well fetch other associated aggregate roots and that a repository is merely a way to find aggregate roots.
我会在创建时将帖子绑定到该位置,以便对于每个位置我都可以(通过存储库)获取关联帖子的列表。它看起来像这样:
创建:
检索:
在幕后,帖子和位置之间的关联将作为多对多表关系来实现。此解决方案存在一个问题:添加新位置需要扫描所有帖子并将它们分配到新位置(如果适用)。
希望有帮助。
I would bind post to the location at creation time so that for each location I can get (through a repository) a list of associated posts. It would look like this:
Creation:
Retrieval:
Under the hood, the association between posts and location would be implemented as a many-to-many table relationship. There is one problem with this solution: adding a new location requires to scan all the posts and assign them to the new location (if applicable).
Hope that helps.
假设您使用了规范模式,您可以使用位置对象构建发布规范吗?然后,您只需将规范传递到您的帖子存储库,并返回结果。
Let's say you used the Specification pattern, could you build a Post Specification using a Location object? Then you just pass the Specification to your Post Repository, and get back the result.