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
绝对是错误的地方。
我正在使用 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
绝对是错误的地方。