Ninject 3.2 OnDeactivation not firing Web API

本文关键字:firing Web API not OnDeactivation Ninject | 更新日期: 2023-09-27 17:59:58

我使用ninject来管理Web API/MVC应用程序的会话。代码如下:

Bind<ISession>().ToMethod(c => c.Kernel.Get<ISessionFactory>().OpenSession())
            .InRequestScope()
            .OnActivation(s => s.BeginTransaction())
            .OnDeactivation((s) =>
            {
                try
                {
                    s.Transaction.Commit();
                }
                catch (Exception e)
                {
                    s.Transaction.Rollback();
                }
                s.Close();
                s.Dispose();
            });
    }

OnActivation代码被正确调用-当会话被注入时,事务就开始了。但是,当请求完成时,不会调用ondactivation。因此,我可以从数据库中查询内容,但不能提交更改(除非我在其他地方提交事务)。

我真的不知道为什么没有调用OnDeactivation——我的ninject设置中遗漏了什么吗?

Ninject 3.2 OnDeactivation not firing Web API

OnDeactivation期间调用Commit是一个非常糟糕的主意,因为即使从业务层内抛出异常,OnDeactivation也将始终被调用。如果出现错误,您显然不想提交事务。

你应该考虑在不同的层面上做出承诺。这个问答更详细地讨论了这个问题,并展示了如何解决这个问题。

还要注意,您的代码过于冗长。如果调用Dispose,则不必调用Close;如果对未提交的事务调用Dispose,则该事务将自动回滚。你甚至可以拔掉插头,数据库会自动回滚一个未提交的事务。换句话说,您可以很容易地将代码简化为以下内容:

.OnDeactivation((s) =>
{
    try
    {
        s.Transaction.Commit();
    }
    finally
    {
        s.Dispose();
    }
});

当您使用OnePerRequestHttpModule时,您甚至可以删除Dispose,如下所述。这将代码进一步缩减为:

.OnDeactivation(s => s.Transaction.Commit());

但是,OnDeactivation绝对是一个错误的地方。