开发者

Nhibernate transactions:Avoiding Nhibernate dependency in the service layer

One of practices advocated by Nhibernate experts is to do all actions in inside a transaction.

In a typical 3 tier web architecture, Nhibernate depedency is limited the data layer.

In such a case is it fine to use

  using (var tr = NHibernateSession.Current.BeginTransaction()) {

at the controller 开发者_JAVA技巧level. Won’t this bring in a dependency on Nhibernate to the service layer?


One way around this is the wrap the NHibernate session and transaction semantics in your own abstrated Interface / implementation class. This way if you ever wanted to say, switch to Linq2Sql, you could create a L2S implementation. However, this still means that transaction semantics will still be in the service layer, but not NHibernate specific calls. Google IRepository<T> for many examples of how to do this.

However, if you don't plan on switching out your ORM in the future, one could argue that having NHibernate in the service layer isn't necessarily a bad thing since NHibernate in itself is the abstraction over the data layer.


I'm also looking to do this but haven't settled on an approach yet for lack of time and some YAGNI.

Here is some code I haven't yet tested, but adapted from the open source SharpArch project. I like the interface alot, but I may have changed the NHib implementation a bit, as there are some things I don't love about SharpArch's repository implementation, but you can judge for yourself.

Of course using NHib session.BeginTransaction() introdues NHib dependencies, and not abstracting this out seems at odds with abstracting out IRepository and everything else. I for one would be very interested in what you conclude as a useful abstraction of transactions.

HTH,
Berryl

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

}


Calls to some static singleton strewn about like that doesn't seem like a good idea to me. Perhaps it would be better to add a dependency on your own "ITransactionFactory" and leave the NHibernate specific code inside the TransactionFactory implementation.

For SharpArchitecture specifically, there is the TransactionAttribute action filter that is designed to wrap your action methods inside transactions.

Concerning assembly references to NHibernate, that's not something I would personally worry about.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜