NHibernate的ITransaction和纯域模型
-
21-09-2019 - |
题
我试着写我的域模型的持久性的无知地。现在我正在做正确的唯一的事情是标识每个属性和方法virtual
,如NHibernate的要求,对于延迟加载。
在我的域模型组件强>我定义一些储存库接口:
public interface IRepository<TEntity> where TEntity : EntityBase {
TEntity Get(int id);
/* ... */
}
public interface IProductRepository : IRepository<Product> { ... }
然后,我有一个的数据组件即可。这其中将引用NHibernate的,它知道它的存在。这是实现那些储存库接口的组件:
public abstract class Repository<TEntity> : IRepository<TEntity> {
public TEntity Get(ind id) { ... }
/* ... */
}
public class ProductRepository : Repository<Product>, IProductRepository {
/* ... */
}
等。
现在我想为实现交易功能,以我的存储库。要做到这一点,我想我的IRepository接口上添加BeginTransaction
方法。然而,我无法定义它的返回类型为NHibernate.ITransaction
,因为我想保持域模型持久性无知,而不是被迫从我的域模型装配参考NHibernate的装配。
你会怎么做?
你会简单地实现void BeginTransaction()
,一个void Commit()
,并在接口上void RollBack()
方法,并让库执行内部管理ITransaction
对象
或者,你会找到一种方式为暴露ITransaction
对象即可让客户端直接与它的管理而不是使用存储库的方式交易,?
谢谢!
解决方案
您可以看看在夏普架构它已经实现一切你说说,包括通用仓库与事务的支持。该解决方案有是IRepository已的DbContext它封装了数据(它实际上是一个接口)属性。 这是第一次,你描述的(自定义交易界面隐藏了NHibernate的)的选项。而且效果很好。
我想你甚至可以重新使用s#ARP代码不管,如果你打算使用完整的框架。
其他提示
IMO事务应该总是启动并在业务逻辑结束,换句话说,该交易应该在服务层开始没有仓库层和库应该争取它在交易自我,理想的情况是隐式进行。
现在,如果你使用NH那么如果你的服务和存储库共享相同的“会话”(他们应该),那么你可以在服务层称之为“的BeginTransaction”和提交或回滚的要求:
例如,想象这上的服务的方法,包括:
public void RegisterCustomer(Customer customer) { try { using(var transaction = _session.BeginTransaction()) { _customerRepository.Save(customer); _customerSurveyRepository.Save(customerSurvey); // DO What ever else you want... transaction.Commit(); } } catch (Exception exn) { throw new AMException(FAILED_REGISTRATION, exn); } }
存储库如何获取到相同的会话的引用可以通过在构造注入或通过使用SessionFactory来获得当前会话来解决...