Nhibernate 让Ninject管理我的事务状态、实践关注点
我让Ninject使用以下注册方法在Fluent NHiberate中管理我的Nhibernate 让Ninject管理我的事务状态、实践关注点,nhibernate,ninject,Nhibernate,Ninject,我让Ninject使用以下注册方法在Fluent NHiberate中管理我的ISession和ITransaction状态-我想知道这是否足以控制事务,或者我是否需要将其放在其他地方 其思想是,每个ISession都是根据请求创建的,而Ninject处理在该请求期间完成的所有提交 public class SessionModule : Ninject.Modules.NinjectModule { private static ISessionFactory sessionFacto
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();
}
}
public类SessionModule:Ninject.Modules.Ninject模块
{
私人静态ISessionFactory sessionFactory;
公共覆盖无效负载()
{
绑定()
.ToMethod(c=>CreateSessionFactory())
.InSingletonScope();
绑定()
.ToMethod(c=>OpenSession())
.InRequestScope()
.OnActivation(会话=>
{
session.BeginTransaction();
session.FlushMode=FlushMode.Commit;
})
.OnDeactivation(会话=>
{
if(session.Transaction.IsActive)
{
尝试
{
session.Flush();
Commit();
}
抓住
{
session.Transaction.Rollback();
}
}
});
}
///
///创建新数据库以连接到数据库。
///
///
///一个构造和映射的模型。
///
私有静态ISessionFactory CreateSessionFactory()
{
if(sessionFactory==null)
sessionFactory=Persistence.sessionFactory.Map
(System.Web.Configuration)
.WebConfiguration Manager
.连接字符串[“本地”]
.连接字符串
);
返回工厂;
}
///
///从中打开一个新的。
///
///
///一个新的。
///
私有静态ISession OpenSession()
{
//检查是否有会话工厂可以从中获取会话
if(sessionFactory==null)
CreateSessionFactory();
//如果没有当前会话,请从工厂打开新会话
返回sessionFactory.OpenSession();
}
}
我已经使用System.Diagnostics.Debug.WriteLine
检查了运行时,以便在事情发生时进行写入,它确实执行了我希望它执行的操作。我要问的是社区,这是否是一种良好的做法。这是我的理解
无数个小时的阅读让我重新评估了很多会话管理的方法
对nHibernate文档的大量挖掘告诉我,每当数据库发生任何事情时,我都需要使用ITransaction
将管理放在属性中被认为是一个缺陷,因为它不符合上述语句
每个操作执行ITransaction
都不是正确的过程,因为它需要(A)我的控制器访问ISession
或(B)我的IRepository
拥有ITransaction
逻辑,我在前面的问题中被告知这不是一个好做法
将我的ITransaction
管理放在HttpModule
中会增加不必要的开销,因为它让我了解ISession
的HttpContext知识,这意味着我必须对HttpRequest
进行某种注入(我可以使用[Inject]
,但这似乎并不明智)
这使我得出了这个结论
- 事务应在请求
时启动ISession
- 在一个请求中发生的每件事都被一个
ISession
- 当
完成时,需要提交它,以便二级缓存可以获得其结果ITransaction
我可以补充的另一点是,在我看来,事务应该按照操作进行显式控制,而不是像代码所建议的那样进行全局控制(请求的开始和开始,最后提交)。
这是因为我相信您希望控制事务的行为—每个操作是否提交(如果不需要DB访问,甚至可能不启动)。
我使用的是一个管理层(或者工作流,如果你愿意的话),它负责这一点。例如:
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();
}
}
}
}
}
希望这能有所帮助我很抱歉没有早点接受。我以为我已经处理好了。非常感谢。我想知道是否有一种方法可以挂接到RequestScope中的
以启动/提交事务。。。谢谢你的帖子!