NHibernate One Session Pre Request Easy Practice
最近园子里面对于 Session-Pre-Request 的模式讨论的很多:
1. http://home.cnblogs.com/group/topic/34139.html
2. http://www.cnblogs.com/Flyear/archive/2009/12/03/1616565.html
我也忍不住侃侃我的实现方法。
Session-Pre-Request 顾名思义,为每个Request生成一个Session,但是会存在一个问题,是不是每个Request都有必要去生成Session呢?如果能实现用时才生成是不是要更好一点呢?
接下来说说我的实现方式:
先贴2段代码
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected override void OnApplicationStarted() {
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn(typeof(HomeController).Assembly);
ServiceLocator.Initialize(Kernel);
}
protected override IKernel CreateKernel() {
return new StandardKernel(new NHibernateModule(), new ServiceModule());
}
}
public override void Load()
{
Bind<ISessionFactory>().ToProvider<SessionFactoryProvider>().InSingletonScope();
Bind<ISession>().ToProvider<SessionProvider>().InRequestScope();
}
}
public class SessionProvider : Provider<ISession>
{
protected override ISession CreateInstance(IContext context)
{
var sessionFactory = context.Kernel.Get<ISessionFactory>();
return sessionFactory.OpenSession();
}
}
public class SessionFactoryProvider: Provider<ISessionFactory>
{
protected override ISessionFactory CreateInstance(IContext context)
{
var sessionFactory = new NHibernateSessionFactory();
return sessionFactory.BuildSessionFactory();
}
}
代码很简单,就这么2段代码就可以实现了,当然,是借助了Ninject这个轻量级的IOC框架的帮助(这个应该就是传说中的站在巨人肩膀上吧)。
整个代码最关键的位置就在于:
Bind<ISessionFactory>().ToProvider<SessionFactoryProvider>().InSingletonScope(); 将SessionFactoryProvider创建出来的ISessionFactory的Instance绑定为Singleton模式。
Bind<ISession>().ToProvider<SessionProvider>().InRequestScope(); 将SessionProvider创建出来的ISession的Instance绑定为PreRequest模式。
NHibernateSessionFactory的GetSessionFactory方式,就是简单的通过读取配置,生成SessionFactory的过程,实现的方式有很多,我是采用FluentNHibernate来实现的,在这里就不贴代码了,如果需要可以给我留言。
使用方法:
private readonly ISession session;
[Inject]
public HomeController(ISession session)
{
this.session = session;
}
[Transaction]
public ActionResult Index() {
session.Save("xxx"); //伪代码
return View();
}
}
Ninject提供多种注入方式,我这里贴的是通过构造函数注入的方式。
到这里基本的实现过程介绍就完成了,感兴趣的话,可以自己实现上面介绍的功能后,打断点跟踪测试一下。一定是用时才生成的。