Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Nhibernate事务:避免服务层中的Nhibernate依赖性_C#_.net_Nhibernate_Transactions_S#arp Architecture - Fatal编程技术网

C# Nhibernate事务:避免服务层中的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实现。然而,这仍

Nhibernate专家提倡的做法之一是

在典型的三层web体系结构中,Nhibernate依赖性仅限于数据层

在这种情况下,是否可以使用

  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(); }

}