我让Ninject使用以下注册方法管理Fluent nHibnerate中的ISession
和ITransaction
状态 - 我想知道它是否足以控制交易,或者我是否需要将其放入在其他地方。
我们的想法是在请求中创建每个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
中会增加不必要的开销,因为它提供了我对HttpContext的ISession
知识,这意味着我必须对HttpRequest
进行某种注入。 [Inject]
(我可以使用ISession
执行此操作,但这似乎并不明智)
这使我得出了这个结论。
ISession
时开始。ITransaction
任何人都可以对此有所了解吗?我终于走上了正轨吗?或者我还是完全错过了这一点?
答案 0 :(得分:2)
我不是专家(并且对ninject没有经验),但我同意你的3个结论,这就是我在项目中所做的。
我可以添加的另一件事是,在我看来,交易应该是明确的和每个操作控制的,而不是全局的(开始和开始请求和最后提交),就像你的代码所暗示的那样。
这是因为我相信你想要控制你的交易的行为提交与否(或者如果不需要数据库访问,甚至可能无法启动)每个操作都是单独的。
我使用的是一个管理(或工作流程,如果你愿意)图层,它只负责这一点。例如:
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();
}
}
}
}
}
希望这会有所帮助