6

我刚刚开始了一个新项目,自然而然地选择使用很多新技术。

我正在使用(流利的)NHibernate、ASP.NET MVC 3 并尝试应用存储库模式。

我决定将我的业务逻辑分离到一个单独的项目中,并定义包装我的存储库的服务,以便我可以返回 POCO 而不是 NHibernate 代理,并在我的前端和 DA 逻辑之间保持更多的分离。这也将使我能够在以后轻松提供与 API 相同的逻辑(要求)。

我选择使用通用IRepository<T>接口,T其中我的 NHibernate 映射实体之一都实现了 IEntity(我的接口实际上只是一个标记)。

问题是这违背了聚合根模式,我开始感受到贫血域模型的痛苦。

如果我改变一个挂在另一个物体上的物体

  • 根 <- 已更改
    • 孩子 <- 改变了

在我的服务中,我必须执行以下操作:

public void AddNewChild(ChildDto child, rootId)
{
    var childEntity = Mapper.Map<ChildDto,ChildEntity>(child);
    var rootEntity = _rootrepository.FindById(rootId);
    rootEntity.Children.Add(childEntity);
    _childRepository.SaveOrUpdate(child);
    _rootRepository.SaveOrUpdate(root);
}

如果我不先救孩子,我会从 NHibernate 得到一个例外。我觉得我的通用存储库(我目前在一项服务中需要 5 个)不是正确的方法。

 public Service(IRepository<ThingEntity> thingRepo, IRepository<RootEntity> rootRepo, IRepository<ChildEntity> childRepo, IRepository<CategoryEntity> catRepo, IRepository<ProductEntity> productRepo)

我觉得不是让我的代码更灵活,而是让它更脆弱。如果我添加一个新表,我需要在我的所有测试中更改构造函数(我使用 DI 来实现,所以这还不错),但它看起来有点臭。

有人对如何重组这种架构有任何建议吗?

我应该让我的存储库更具体吗?服务抽象层是不是太过分了?

编辑:有一些很好的相关问题有帮助:

4

2 回答 2

2

当您有一个聚合时,聚合父(根)及其子的存储库是相同的,因为子的生命周期由根对象控制。

您的根对象类型的“保存”方法也应该直接负责将更改保存到子记录,而不是将其委托给另一个存储库。

此外,在“适当的”聚合模式中,子记录没有自己的身份(至少一个在聚合之外可见)。这有几个直接的后果:

  1. 这些子记录的外部记录/聚合中不能有外键。
  2. 从第 1 点开始,每次保存根对象状态时,您都可以在数据库中删除并重新创建子记录。如果遇到优先级问题,这通常会使您的持久性逻辑更容易。

注意:1. 的相反情况是不正确的。聚合中的子记录可以具有其他根记录的外键。

于 2011-02-16T19:47:46.120 回答
1

我觉得不是让我的代码更灵活,而是让它更脆弱。如果我添加一个新表,我需要在我的所有测试中更改构造函数(我使用 DI 来实现,所以这还不错),但它看起来有点臭。

在您的存储库中实现工作单元模式。这意味着实际上你有一个工作单元类,它通过 ctor 或属性注入来保存你的服务注入。此外,它还拥有提交和/或事务方法。仅在您的服务中注入 IUnitOfWork 实例。添加存储库时,您只需更改工作单元而不涉及业务逻辑(服务)。

于 2013-04-26T10:28:13.407 回答