什么是确保您的信息库和的UnitOfWork类共享相同的NHibernate会话对象的正确方法?(W

2019-09-23 04:35发布

我有问题,编辑和删除对象,我认为它是因为我没有分享我的仓库类和我的UnitOfWork类之间的相同会话对象。 我试图找到最好的方式一些文件中这样组装起来,所以我共享相同的会话对象。

我使用ninject作为MVC开发的网站我的IOC容器。

Answer 1:

我通常设置会话作为仓库的依赖,因此Ninject可以解决的依赖(的Isession = NHibernate.ISession):

public UserRepository(ISession session)
{
    ...
}

这是我的设置绑定:

kernel.Bind<ISession>().ToMethod(x => GetRequestSession()).InRequestScope();

因此需要一个会话时Ninject会调用GetRequestSession()来检索会话。 该功能的实现如下:

private static ISession GetRequestSession()
        {
            IDictionary httpContextItems = HttpContext.Current.Items;

            ISession session;
            if (!httpContextItems.Contains(MvcApplication.SESSION_KEY))
            {
                // Create an NHibernate session for this request
                session = MvcApplication.SessionFactory.OpenSession();
                httpContextItems.Add(MvcApplication.SESSION_KEY, session);
            }
            else
            {
                // Re-use the NHibernate session for this request
                session = (ISession)httpContextItems[MvcApplication.SESSION_KEY];
            }
            return session;
        }

NHibernate会话存储在HttpContext的项目。 这是一个关键值集合可使用的一个请求的handlng期间存储和共享数据。

会话创建每个请求只有一次,并且该请求期间重新使用。

MvcApplication.SESSION_KEY仅仅是一个常量字符串我在Global.asax中定义为能够从HttpContext的存储和检索会话。 另外,会议工厂位于Global.asax中,并在启动时被创建。

你的工作类的单位也可以将它的Isession作为依赖,所以Ninject将解决这种依赖关系,以及因此使用相同的会话。 在另一方面,你可能不需要工作类的单位,因为NHibernate的本身实现的Isession已经是工作类的单位。

我不知道这是否是最好的做法,但它的作品完美的我。



Answer 2:

NHibernate的有一个内置的机制来共享会话,也就是上下文。 基于应用程序,您可以使用适当的范围内。 更多细节,

http://nhibernate.info/doc/nhibernate-reference/architecture.html#architecture-current-session



Answer 3:

如果罗宾的答案是不适合你的工作,你可以有一个Ninject错误配置。

今天早上我遇到了一个非常类似的问题与更新。 在我来说,我在读从一个不同的范围比我写会话绑定到一个对象的会话对象。

这里是我的简单,SessionProvider:

public class SessionProvider : Provider<ISession>
{
    protected override ISession CreateInstance(IContext context)
    {
        var factory = context.Kernel.Get<ISessionFactory>();
        var session = factory.OpenSession();
        return session;
    }
}

和IOC的代码:

        kernel.Bind<ISessionFactory>().ToProvider<SessionFactoryProvider>();
        kernel.Bind<ISession>().ToProvider<SessionProvider>().InRequestScope();

确保在您的工作单位和你的版本库的最简单方法是使用相同的ISession实例是,以确保他们也都在要求范围内创建。 然而,这应该是默认的。

根据您如何安装NInject和你正在使用,您可能必须安装一个HTTP模块,以确保请求范围的版本可以正常工作:

  1. 如果安装了NuGet包,这将增加DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
  2. 如果你有Ninject的旧版本,你也可以将模块使用添加到web.config中<add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/>
  3. 如果您使用的是较新的Ninject,它在<add name="OnePerRequestHttpModule" type="Ninject.Web.Common.OnePerRequestHttpModule, Ninject.Web.Common"/>


文章来源: What is the right way to ensure your Repository and UnitOfWork class share the same nhibernate session object?