C# Nhibernate事务:避免服务层中的Nhibernate依赖性
Nhibernate专家提倡的做法之一是 在典型的三层web体系结构中,Nhibernate依赖性仅限于数据层 在这种情况下,是否可以使用C# Nhibernate事务:避免服务层中的Nhibernate依赖性,c#,.net,nhibernate,transactions,s#arp-architecture,C#,.net,Nhibernate,Transactions,S#arp Architecture,Nhibernate专家提倡的做法之一是 在典型的三层web体系结构中,Nhibernate依赖性仅限于数据层 在这种情况下,是否可以使用 using (var tr = NHibernateSession.Current.BeginTransaction()) { 在控制器级别。这不会给服务层带来对Nhibernate的依赖吗?一种解决方法是将Nhibernate会话和事务语义包装到您自己的抽象接口/实现类中。这样,如果您想说,切换到Linq2Sql,您可以创建一个L2S实现。然而,这仍
using (var tr = NHibernateSession.Current.BeginTransaction()) {
在控制器级别。这不会给服务层带来对Nhibernate的依赖吗?一种解决方法是将Nhibernate会话和事务语义包装到您自己的抽象接口/实现类中。这样,如果您想说,切换到Linq2Sql,您可以创建一个L2S实现。然而,这仍然意味着事务语义仍然在服务层中,而不是特定于NHibernate的调用。Google
IRepository
提供了许多这样做的例子
然而,如果你不打算在将来关闭你的ORM,有人可能会说在服务层中使用NHibernate并不一定是一件坏事,因为NHibernate本身就是数据层的抽象。我也在考虑这样做,但由于缺乏时间和一些原因,还没有确定一种方法 下面是一些我还没有测试过的代码,它们是从开源SharpArch项目改编而来的。我非常喜欢这个界面,但我可能对NHib的实现做了一些更改,因为SharpArch的存储库实现中有一些我不喜欢的地方,但是您可以自己判断 当然,使用NHib session.BeginTransaction()会引入NHib依赖项,不将其抽象出来似乎与抽象出IRepository和其他所有内容不一致。就我个人而言,我对您总结的有用的交易抽象非常感兴趣 HTH,
贝里尔
公共接口IDbContext{
无效提交更改();
IDisposable BeginTransaction();
无效提交交易();
作废回滚事务();
}
公共类DbContext:IDbContext{
专用只读会话;
公共数据库上下文(ISession会话)
{
检查。要求完整(会话);
_会话=会话;
}
public void CommitChanges(){u session.Flush();}
公共IDisposable BeginTransaction(){return_session.BeginTransaction();}
public void CommitTransaction(){u session.Transaction.Commit();}
public void RollbackTransaction(){u session.Transaction.Rollback();}
}
打电话给一些散落在各处的静态单身汉对我来说似乎不是个好主意。也许最好在您自己的“ITransactionFactory”上添加一个依赖项,并将特定于NHibernate的代码留在TransactionFactory实现中
特别是对于SharpArchitecture,有TransactionAttribute操作过滤器,用于将操作方法包装到事务中
关于NHiBiNeT的程序集引用,这不是我个人担心的问题。
+ 1如果你发现你需要在项目中间切换ORMS,你就有比这更大的问题。+ 1,我们确实切换了ORMS(iBATS->NHiBiNATE)。很明显,在很早的时候我们就需要进行转换。事实上,我正在从亚音速向非音速转变。这虽然不常见,但也不罕见。通过将所有NH依赖项放在数据层中,从一个分层体系结构来看,事情看起来很整洁。我认为这可以归结为如果您想进行以下权衡:您可以通过存储库模式抽象您的ORM,以获得服务层中的ORM无知,但代价是,您将失去一些ORM最好的特性,因为ORM之间的特性非常丰富。使用NHibernate,您将放弃未来的查询、多查询、批插入等。。。这里没有明确的对与错,而是要做出选择以实现最终目标。不幸的是,TransactionAttribute是web.mvc的actionfilter属性。如果考虑到从idisposable实现idbcontext,则需要将其更改为与WebFormsShave u一起使用public interface IDbContext {
void CommitChanges();
IDisposable BeginTransaction();
void CommitTransaction();
void RollbackTransaction();
}
public class DbContext : IDbContext {
private readonly ISession _session;
public DbContext(ISession session)
{
Check.RequireNotNull<ISession>(session);
_session = session;
}
public void CommitChanges() { _session.Flush(); }
public IDisposable BeginTransaction() { return _session.BeginTransaction(); }
public void CommitTransaction() { _session.Transaction.Commit(); }
public void RollbackTransaction() { _session.Transaction.Rollback(); }
}