2011-03-19 49 views
11

我让Ninject使用以下注册方法管理我的ISessionITransaction状态,使用以下注册方法 - 我想知道是否有足够的交易控制权,或者我是否需要投入这个别的地方。让Ninject管理我的交易状态,练习关注

思想是每个ISession都是在请求上创建的,并且Ninject处理在该请求期间完成的所有事务的提交。

public class SessionModule : Ninject.Modules.NinjectModule 
{ 
    private static ISessionFactory sessionFactory; 

    public override void Load() 
    { 
     Bind<ISessionFactory>() 
      .ToMethod(c => CreateSessionFactory()) 
      .InSingletonScope(); 

     Bind<ISession>() 
      .ToMethod(c => OpenSession()) 
      .InRequestScope() 
      .OnActivation(session => 
      { 
       session.BeginTransaction(); 
       session.FlushMode = FlushMode.Commit; 
      }) 
      .OnDeactivation(session => 
      { 
       if (session.Transaction.IsActive) 
       { 
        try 
        { 
         session.Flush(); 
         session.Transaction.Commit(); 
        } 
        catch 
        { 
         session.Transaction.Rollback(); 
        } 
       } 
      }); 
    } 

    /// <summary> 
    /// Create a new <see cref="NHibernate.ISessionFactory"/> to connect to a database. 
    /// </summary> 
    /// <returns> 
    /// A constructed and mapped <see cref="NHibernate.ISessionFactory"/>. 
    /// </returns> 
    private static ISessionFactory CreateSessionFactory() 
    { 
     if (sessionFactory == null) 
      sessionFactory = Persistence.SessionFactory.Map 
       (System.Web.Configuration 
        .WebConfigurationManager 
        .ConnectionStrings["Local"] 
        .ConnectionString 
       ); 
     return sessionFactory; 
    } 

    /// <summary> 
    /// Open a new <see cref="NHibernate.ISession"/> from a <see cref="NHibernate.ISessionFactory"/>. 
    /// </summary> 
    /// <returns> 
    /// A new <see cref="NHibernate.ISession"/>. 
    /// </returns> 
    private static ISession OpenSession() 
    { 
     // check to see if we even have a session factory to get a session from 
     if (sessionFactory == null) 
      CreateSessionFactory(); 

     // open a new session from the factory if there is no current one 
     return sessionFactory.OpenSession(); 
    } 
} 

我已经研究使用System.Diagnostics.Debug.WriteLine发生的事情的时候写的运行时,它确实这个样子的是做什么的我它做的事。我问你,社区,这是否是实践或不。这是我的理解。

http://ayende.com/blog/default.aspx上无数个小时的阅读导致我重新评估了很多进行会话管理的方式。

大量挖掘nHibernate文档告诉我,我需要使用ITransaction每次发生任何事情与我的数据库

将管理置于属性中被认为是一个缺陷,因为它不符合上述声明。

每个单独的操作做ITransaction是不正确的过程,因为它需要是(A)我的控制器能够访问的ISession或(B)我IRepository<T>ITransaction逻辑,这是我在以前被告知问题不是一个好的做法。

把我ITransaction管理在HttpModule增加非neccessary开销,因为它给我的ISession的HttpContext的知识,这意味着我必须做某种注射入HttpRequest(我可以用[Inject]做,但它似乎并不明智)

这使我得出了这个结论。

  • 交易应该在请求ISession时开始。这种情况发生在单个请求
  • 一切都是由一个ISession
  • 封装当ITransaction完成,它需要致力于使二级高速缓存可以得到它的结果。

任何人都可以阐明这一点吗?我终于走上正轨吗?还是我完全错过了这个观点?

+0

我在想,如果有挂接到'InRequestScope'开始/提交事务...感谢您的文章的方式! – user1068352 2012-12-10 14:45:14

回答

2

我不是专家(也没有ninject的经验),但我同意你的3个结论,这就是我在我的项目中所做的。
我可以补充的另一件事是,在我看来,交易应该明确地按照操作进行控制,而不是全局的(最终请求的开始和开始),就像你的代码所暗示的那样。
这是因为我相信你想控制你的事务的行为提交与否(或者甚至不需要启动,如果没有必要的DB访问是必需的)每个操作单独。
我使用的是一个管理层(或者工作流程,如果你愿意的话)层,它只是为此负责。例如:

public class SomeManager : ManagersBase 
{ 
    public void DoSomething(DomainObject obj) 
    { 
     if (obj.Operation()) 
     { 
      using (ITransaction tx = Session.BeginTransaction()) 
      { 
       try 
       { 
        Session.Update(obj); 
        tx.Commit(); 
       } 
       catch (MeaningfulException ex) 
       { 
        //handle 
        tx.Rollback(); 
       } 
      } 
     } 
    } 
} 

希望这有助于

+0

我很抱歉没有及早接受此事。我以为我照顾过它。非常感谢你。 – Ciel 2011-05-10 14:18:12