Ninject 3.2 OnDeactivation 不触发 Web API

Ninject 3.2 OnDeactivation not firing Web API

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

我不太确定为什么没有调用 OnDeactivation - 我是否在 ninject 设置中遗漏了什么?

OnDeactivation 期间调用 Commit 是一个非常糟糕的主意,因为 OnDeactivation 总是 被调用,即使抛出异常来自业务层。如果出现错误,您显然不想提交交易。

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

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

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

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

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

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