我目前的观点是存储库应该包含特定于实体的修改方法,如Add,Delete等,而UnitOfWork应该只包含与它相关的方法,如Commit(也称为SaveChanges,SubmitChanges)和Rollback。 (也称为ClearChanges)。但Martin Fowler在article关于UnitOfWork的建议中建议将所有修改方法添加到UnitOfWork。
那么现在哪种方式在EF和NHibernate的世界中更好?
更新 我应该注意,即使采用我更好的方法,最后通过存储库的所有修改都会进入内置于EF Context或NHibernate Session的UnitOfWork。而我的UnitOfWork更像是UnitOfWorkManager(它管理内部ORM UnitOfWork)。
答案 0 :(得分:5)
在NHibernate世界中,由ISession实现的UnitOfWork的主要功能。 ISession会跟踪已更改的内容,您不需要使用RegisterClean或RegisterDirty等方法。对于较大的项目,通过使用您自己的可称为UnitOfWork的类来隐藏ISession是很有用的。例如:
public class UnitOfWork {
private readonly ISession _session;
public void BeginTransaction();
public void Commit();
public void Rollback();
public IRepositoryFactory AllRepositories;
}
将ISession隐藏在应用程序代码中的优点是,此代码不会直接引用NHibernate,从而实现更好的分层。换句话说,应用层将更难直接开始使用NHibernate API,绕过数据访问层。
存储库本身将包含添加新对象和可能删除的方法:
public interface IOrdersRepository {
public IList<Order> FindPending();
public void AddNew(Order order);
public void Delete(Order order);
}
答案 1 :(得分:3)
这是两种不同的模式。
Repository负责从上层抽象数据存储,而Unit Of Work负责业务事务管理。存储库允许您在不更改代码的情况下替换存储 - 您可以使用文本文件,XML,数据库 - 无论如何。 UoW使您有机会控制和跟踪实体的更改,并一次性保留一个业务事务的所有更改。
默认情况下,EF和NH都支持UoW,因此您无需自行重新实现。您仍然希望编写自己的存储库模式,因为这些ORM不提供开箱即用的功能。
在NH和EF之上的UoW是不必要的抽象级别,可以被视为反模式。
在那篇文章中,福勒实际上并没有建议将数据操作的责任添加到UoW。他所说的是你可以跟踪对象的更改,并根据需要刷新/回滚它们。