2011-02-27 20 views
3

我有下面的代码接线1的NHibernate的ISession在Autofac的ASP.NET应用程序:OnRelease过程中是否会发生异常,导致组件未正确配置?

builder.RegisterAdapter<ISessionFactory, ISession>(factory => factory.OpenSession()) 
    .InstancePerHttpRequest() 
    .OnActivated(activatedArgs => 
       { 
        var session = activatedArgs.Instance; 
        session.BeginTransaction(); 
       }) 
    .OnRelease(session => 
       { 
        if (session.Transaction != null && session.Transaction.IsActive) 
        { 
         try 
         { 
          session.Transaction.Commit(); 
         } 
         catch(Exception e) 
         { 
          session.Transaction.Rollback(); 
          throw; 
         } 
        } 
       }); 

将在本届会议正确地甚至抛出的异常配置在提交?这是ISession和autofac的正确用法吗?

回答

2

没有投掷在Dispose()与Autofac不是一个好主意。无法保证正确处理其他组件实例。

总的来说应该避免 - 例如WCF有一个众所周知的和长期存在的可用性问题,因为在处理过程中抛弃了连接。基本的反模式是经常调用Dispose(),因为异常正在传播。抛出的另一种例外掩盖了原来的

编辑:

作为一个思想实验 - 让我们说这是使用Autofac一些try/catch语句神奇的支持。如果OnRelease()引发两个不同的组件,会发生什么情况?我们不能传播这两个例外。更进一步 - 一旦Autofac冒出异常,谁能抓住它呢?为请求提供服务的所有组件现在都已发布。

希望这有助于尼克。

+0

当组件Dispose()d时调用OnRelease(),所以这结束成为一个不好的理想?我的想法是在会话使用时将会话使用包装在事务中。我可以打扰你这种行为的替代实施吗? – 2011-02-28 14:28:21

+0

嗨布鲁诺 - 在自定义动作调用程序(如果您使用MVC)调用Commit()是我知道的最佳选择。 – 2011-02-28 21:34:14

+0

我正在使用webforms,所以也许我会在HttpModule上做到这一点。这只会提出如果没有完成工作就不会创建/提交交易的问题,我想。 – 2011-03-01 01:11:59

0

我不知道Autofac中的NHibernate ISession,但是如果你的会话类有一个Dispose()方法,那么你不会在任何地方调用它。你应该在catch块之后添加一个finally块并在那里处理它。

+0

Autofac所做的一部分工作是在组件释放时处置组件。当我使用OnRelease时,我的问题必须做,如果Autofac在将通知链传递给异常之前/之后仍将它抛弃,则会引发异常。如果是这样,那么在这里调用Dispose将是不正确的,因为它也将被称为进一步调用链。 – 2011-02-27 18:16:21

+0

@布鲁诺,如果他们的实施是正确的,在这里处理它应该没有害处。你总是可以试试看看你是否得到ObjectDisposed异常:)对不起,我没有太多的帮助,因为我不知道Autofac等 – 2011-02-28 03:07:22

相关问题