工作类的单元如何知道提交时调用哪个存储库?
本文关键字:调用 存储 提交 单元 何知道 工作 | 更新日期: 2023-09-27 18:09:52
*序:对单位工作模式比较陌生*
我的目标是实现一个工作类单元,它将能够跟踪在给定事务中已更改的所有对象。我读到的关于工作单元模式的所有内容都与存储库模式并列。这就是我想用的方法。
例如,我创建了一个新的User。在我的工作对象单元上,我有一个新创建对象的列表,因此我将我的新User添加到该列表中。我的用户存储库有一个名为Create的方法,它接受一个user并调用一个存储过程将数据添加到数据库中。当我在我的工作单元上调用commit时,它如何根据新对象列表知道调用哪个存储库和方法?假设它包含一个User对象和一个Comment对象。两者都是新创建的,需要在提交时添加。我不确定如何完成这件事。
谁能解释得更好一点,甚至一个小的例子,如果可能的话?
谢谢。
UnitOfWork是一个已经由ORM实现的基础架构模式,就像Identity Map一样。你不必重新发明轮子。另一方面,存储库是域模型的一部分。Repository和UnitOfWork在不同的层次上运行。UnitOfWork不需要调用Repository,因为它不知道Repository是什么。它处理不同的抽象。它有一个实体的内置缓存,它知道这些实体处于什么状态。但是,UnitOfWork可以被注入到Repository中。
正确实现UnitOfWork, IdentityMap, Change Tracking, Lazy loading是乏味的。您应该真正使用现有的ORM作为基础架构层,帮助您专注于重要的内容-域。
解决这个问题最常用的方法之一是使用控制反转。
例如,您有您的类User和Comment,并且您已经实现了一个通用存储库IRepository<TDomainObject>
。这是获取用户或评论的存储库只是给TDomainObject参数:
-
IRepository<User>
-
IRepository<Comment>
之后你已经配置了谁实现IRepository<User>
和IRepository<Comment>
,所以如果你使用像Microsoft Pattern &实践的公共服务定位器,我们在你的工作单元的提交方法的主体中:
foreach(DomainObject some in NewObjects)
{
((IRepository<DomainObject>)ServiceLocator.Current.GetInstance(Type.GetType(string.Format("NamespacesToGenericRepository.IRepository`1[[{0}]]", some.GetType().FullName)))).Add(some);
}
注意IRepository<TDomainObject>
有一个逆变TDomainObject泛型参数,该类型必须继承DomainObject的基类型DomainObject,它允许将类似IRepository<User>
的东西向上转换为IRepository<DomainObject>
。
换句话说,您的IRepository<TDomainObject>
接口签名看起来像这样:
public interface IRepository<out TDomainObject>
where TDomainObject : DomainObject
这只是关于如何实现定位具体存储库的总结和/或提示,以便域对象的工作单元可以管理任何专门的域对象。
如果您想了解更多关于控制反转的信息,请查看这篇维基百科文章:
- http://en.wikipedia.org/wiki/Inversion_of_control
并且,根据我自己的经验,我想建议您将Castle Windsor作为控制反转框架的选择:
- http://www.castleproject.org/container/
这通常通过更改跟踪实现,无论在实体上发生什么操作,工作单元/会话/上下文都知道并在提交时执行适当的操作。
变更状态可以包括New, Modified和Deleted.
点击此链接获取更多信息。
使用它的实现可能有助于获得更好的想法。
实体框架实现工作单元模式。也许使用它会让你更好地理解它。
您有多种方法:
- 变更跟踪,通过创建一个UnitOfWork类将变更存储在内存中,直到您要求提交,实现可以是:RegisterAdd(entity), RegisterDelete(entity), RegisterUpdate(entity), ....然后提交();它将遍历所有已注册的更改并提交。(http://msdn.microsoft.com/en-us/magazine/dd882510.aspx)
- 您可以使用TransactionScope作为分布式事务来分组所有更新并在工作单元结束时提交。(如何仅使用TransactionScope和sqlconnections实现工作单元)