请求范围内的NInject, NHIbernate和session
本文关键字:NHIbernate session NInject 范围内 请求 | 更新日期: 2023-09-27 18:14:31
我基本上使用了一个我在很多地方见过的例子,但我不相信它能正常工作。
所以,我有以下内容:
public class NHibernateHelper
{
private readonly string _connectionString;
private ISessionFactory _sessionFactory;
public ISessionFactory SessionFactory
{
get { return _sessionFactory ?? (_sessionFactory = CreateSessionFactory()); }
}
public NHibernateHelper(string connectionString)
{
_connectionString = connectionString;
}
private ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(FluentNHibernate.Cfg.Db.MySQLConfiguration.Standard
.Dialect("NHibernate.Spatial.Dialect.MySQLSpatialDialect,NHibernate.Spatial.MySQL")
.ConnectionString(_connectionString))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<EventListing>())
.ExposeConfiguration(x =>
{
x.SetProperty(NHibernate.Cfg.Environment.CurrentSessionContextClass, ConfigurationManager.AppSettings["current_session_context_class"]);
})
.BuildSessionFactory();
}
}
在我的Ninject启动中我有
private static void RegisterServices(IKernel kernel)
{
NHibernateHelper helper = new NHibernateHelper(WebConfigurationManager.ConnectionStrings["eventlisting"].ConnectionString);
kernel.Bind<ISessionFactory>().ToConstant(helper.SessionFactory).InSingletonScope();
kernel.Bind<ISession>().ToProvider(new SessionProvider()).InRequestScope();
kernel.Bind(typeof(IReadOnlyRepository<>)).To(typeof(ReadOnlyRepository<>)).InRequestScope();
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope();
}
和我的会话提供程序类看起来像
public class SessionProvider : Provider<ISession>
{
protected override ISession CreateInstance(IContext context)
{
ISession session = DependencyResolver.Current.GetService<ISessionFactory>().OpenSession();
session.FlushMode = FlushMode.Auto;
return session;
}
}
令我困惑的是,尽管声明issession应该在请求范围内创建,但它似乎在每个请求中多次击中CreateInstance方法,并且看起来正在生成多个会话。
。如果我有一个带有以下构造函数的控制器:
public SomeController(
IRepository<SomeClass> someClassRepository,
IRepository<SomeOtherClass> someOtherClassRepository)
{
_someClassRepository = someClassRepository;
_someOtherRepository = someOtherClassRepository;
}
则CreateInstance方法被调用两次(我应该为存储库添加一个ISession参数的构造函数):
public Repository(ISession session)
{
this.Session = session;
}
我认为有它作为InRequestScope将意味着它只被调用一次。这是我的误解还是我错过了一些代码的地方。
我做了一个快速测试来验证ninject的"基本"作用域和提供者功能是否正常工作:
public class StringProvider : Provider<string>
{
protected override string CreateInstance(IContext context)
{
return context.ToString();
}
}
var kernel = new StandardKernel();
kernel.Bind<string>().ToProvider(new StringProvider()).InSingletonScope();
kernel.Get<string>();
kernel.Get<string>();
kernel.Get<string>();
在这种情况下,StringProvider.CreateInstance(..)
只被正确地调用一次。
我相信你的问题是提供.InRequestScope()
的ninject扩展的正确配置。可悲的事实是,当它没有正确配置时,它不会对你大喊大叫/抛出异常,不,它会保持安静。只有当意想不到的行为咬了你的屁股时,你才会发现;-)
见这里:ASP。. NET MVC + Ninject: InRequestScope