我正在一个新项目中工作,并且我试图在asp.net mvc中使用ninject实现nhibernate。我有错误:
NHibernate.HibernateException:没有绑定到当前上下文的会话
以下是我使用的代码:
using FluentNHibernate.Automapping;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Conventions.Helpers;
using NHibernate;
using NHibernate.Context;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestNhibernateSessions
{
public class SessionFactory : IHttpModule
{
private static readonly ISessionFactory _SessionFactory;
static SessionFactory()
{
_SessionFactory = CreateSessionFactory();
}
public void Init(HttpApplication context)
{
context.BeginRequest += BeginRequest;
context.EndRequest += EndRequest;
}
public void Dispose()
{
}
public static ISession GetCurrentSession()
{
return _SessionFactory.GetCurrentSession();
}
private static void BeginRequest(object sender, EventArgs e)
{
ISession session = _SessionFactory.OpenSession();
session.BeginTransaction();
CurrentSessionContext.Bind(session);
}
private static void EndRequest(object sender, EventArgs e)
{
ISession session = CurrentSessionContext.Unbind(_SessionFactory);
if (session == null) return;
try
{
session.Transaction.Commit();
}
catch (Exception)
{
session.Transaction.Rollback();
}
finally
{
session.Close();
session.Dispose();
}
}
private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("DefaultConnection")))
.Mappings(m => m.AutoMappings.Add(CreateMappings()))
.CurrentSessionContext<WebSessionContext>()
.BuildSessionFactory();
}
private static AutoPersistenceModel CreateMappings()
{
return AutoMap
.Assembly(System.Reflection.Assembly.GetCallingAssembly())
.Where(t => t.Namespace != null && t.Namespace.EndsWith("Domain"))
.Conventions.Setup(c => c.Add(DefaultCascade.SaveUpdate()));
}
}
}
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(TestNhibernateSessions.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(TestNhibernateSessions.App_Start.NinjectWebCommon), "Stop")]
namespace TestNhibernateSessions.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using TestNhibernateSessions.Repository;
using TestNhibernateSessions.Service;
using NHibernate;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IProductRepository>().To<ProductRepository>();
kernel.Bind<IProductService>().To<ProductService>();
}
}
}
答案 0 :(得分:1)
由于您正在使用Ninject,我的建议是使用它来注入会话工厂而不是IHttpModule。为此,请创建Ninject Provider类,如下所示。请注意,这需要在代码中进行事务管理,我不喜欢在请求期间盲目地保持事务处理的想法。
public class SessionFactoryProvider : Provider<ISessionFactory>
{
protected override ISessionFactory CreateInstance(IContext context)
{
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("DefaultConnection")))
.Mappings(m => m.AutoMappings.Add(CreateMappings()))
.CurrentSessionContext<WebSessionContext>()
.BuildSessionFactory();
}
}
public class SessionProvider : Provider<ISession>
{
protected override ISession CreateInstance(IContext context)
{
var sessionFactory = context.Kernel.Get<ISessionFactory>();
var session = sessionFactory.OpenSession();
session.FlushMode = FlushMode.Commit;
return session;
}
}
然后在NinjectWebCommon中:
private static void RegisterServices(IKernel kernel)
{
// session factory instances are singletons
kernel.Bind<ISessionFactory>().ToProvider<SessionFactoryProvider>().InSingletonScope();
// session-per-request
kernel.Bind<ISession>().ToProvider<SessionProvider>().InRequestScope();
}