【问题标题】:ninject create NHibernate UnitOfWork only one time, every subsequent instantiation return previous UoW with closed sessionninject 只创建一次 NHibernate UnitOfWork,每个后续实例化都返回先前的 UoW 并关闭会话
【发布时间】:2016-06-27 19:32:56
【问题描述】:

我在我的 aspx 页面中使用 ninject.web in this way

我的问题在于 Nhibernate 会话管理。

这是我的 ninject 模块:

public override void Load()
{
    Bind<IUnitOfWork>().To<UnitOfWork>();
    Bind<IAttivitaRepository>().To<AttivitaRepository>();
}

page_load 和单个页面中的每个按钮都以这种方式创建和处理一个工作单元:

using (iuow)
{
    iuow.DoSomething();
    iuow.SaveAll();
}

在 pageLoad 中有效,但页面中的所有其他尝试将 iuow 与新的 Using 块一起使用,返回该会话已关闭

这是我的 UoW 实现:

public UnitOfWork()
        {
            _nhHelper = new SessionFactory();
            InizializzaSessione();
            _transaction = _session.BeginTransaction();
        }

        private void InizializzaSessione()
        {
            if (_session == null)
            {
                _session = _nhHelper.OpenSession();
            }
            Area = new AreaRepository(this._session);
            Attivita = new AttivitaRepository(this._session);           
            Societa = new SocietaRepository(this._session);
            Persona = new PersonaRepository(this._session);         
        }

        /// <summary>
        /// Salva le modifiche sulla base dati
        /// </summary>
        public void SaveAll()
        {
            if (_transaction != null)
            {
                _transaction.Commit();              
                _transaction = null;
            }
        }

在我看来,iuow 仅在页面加载时才被解决(通过调用 New),因此每次创建 Uow 的新尝试都返回上次使用的会话已处理。

在尝试使用 ninject 之前,我所做的只是:

using (Iuow = new UnitOfWork())
{
    ....
}

一切正常

附言 我必须从绑定中删除InRequestScope,因为它甚至会阻止页面加载工作

【问题讨论】:

  • 我从未使用过ninject,但肯定是using语句正在关闭会话,删除它并在完成后关闭会话。
  • 我希望新的 using 块创建一个新的 UnitOfWork,而不是重用现有的一个

标签: c# asp.net session nhibernate ninject


【解决方案1】:

替换

using (iuow)
{
    ...
}

通过

using (IResolutionRoot.Get<IUnitOfWork>())
{
    ...
}

而您可以将IResolutionRoot 注入到您的课程中。不需要额外的绑定(它是 Ninject 类型)。

警告:这是service locator。

或者,您可以将IResolutionRoot.Get&lt;IUnitOfWork&gt;() 隐藏在IUnitOfWorkFactory 后面,您可以手动实现或使用Ninject.Extensions.Factory 为您执行此操作。

示例

using Ninject;
using Ninject.Syntax;

namespace NinjectTest.SO38013150
{
    public interface IUnitOfWork { }

    internal class UnitOfWork : IUnitOfWork { }

    public interface IUnitOfWorkFactory
    {
        IUnitOfWork Create();
    }

    internal class UnitOfWorkFactory : IUnitOfWorkFactory
    {
        private readonly IResolutionRoot resolutionRoot;

        public UnitOfWorkFactory(IResolutionRoot resolutionRoot)
        {
            this.resolutionRoot = resolutionRoot;
        }

        public IUnitOfWork Create()
        {
            return this.resolutionRoot.Get<IUnitOfWork>();
        }
    }
}

通过测试表明它可以工作(这使用 xunit 进行测试,使用 FluentAssertions 进行断言。它们是 nuget 包):

using FluentAssertions;
using Ninject;
using Xunit;

namespace NinjectTest.SO38013150
{
    public class Test
    {
        [Fact]
        public void Foo()
        {
            var kernel = new StandardKernel();
            kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
            kernel.Bind<IUnitOfWorkFactory>().To<UnitOfWorkFactory>();

            var factory = kernel.Get<IUnitOfWorkFactory>();

            var unitOfWork1 = factory.Create();
            var unitOfWork2 = factory.Create();

            unitOfWork1.Should().NotBeSameAs(unitOfWork2);
        }
    }
}

该代码也可作为我的示例集合的一部分,here

【讨论】:

  • IUnitOfWorkFactory 必须在我的 Nhibernate 项目中实现,或者它是 IResolutionRoot 方法的 web 项目中的简单 ninject 封装?
  • @gt.guybrush 这是对IResolutionRoot.Get&lt;IUnitOfWork&gt;() 的简单封装——只需几行代码。应放置在组合根 = 网络项目中。
  • @gt.guybrush 我做了一个快速检查,搜索“[ninject] unit of work factory”返回了很多搜索结果。其中一些甚至与您的要求有关。当然,浏览所有这些内容将需要 1-4 小时的努力。为了让您受益匪浅,我用一个完整的工作示例扩展了我的答案,包括using 指令,以确保这不是绊脚石......
  • @gt.guybrush 那是保持工厂绑定的好地方。工厂接口应该是IUnitOfWork 接口所在的位置。实现应该在 web-application 项目中。
  • @gt.guybrush 这根本没有任何意义。仍然会有确切的 1 实例,一旦它是 .Dispose()d 就不能使用(顺便说一句,这是在每个 using 块的末尾发生的事情!)。您需要一种机制来为每个所有者对象(页面?)创建多个实例。这就是工厂——它是 new 操作符的替代品。
猜你喜欢
  • 1970-01-01
  • 2014-04-25
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-21
  • 2018-10-16
相关资源
最近更新 更多