ninject只创建一次NHibernate UnitOfWork,每次后续实例化返回前一个关闭会话的UoW

时间:2016-06-24 12:10:10

标签: c# asp.net session nhibernate ninject

我在我的aspx页面in this way

中使用了ninject.web

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

这是我的ninject模块:

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

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

using (iuow)
{
    iuow.DoSomething();
    iuow.SaveAll();
}
pageLoad中的

工作,但页面中的每个其他尝试都使用带有新的Using块的iuow,返回该会话已关闭

这是我的UoW impl:

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())
{
    ....
}

一切正常

P.S。 我必须从绑定中删除InRequestScope,因为它阻止了页面加载工作

1 个答案:

答案 0 :(得分:1)

替换

using (iuow)
{
    ...
}

通过

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

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

警告:这是service locator

或者,您可以隐藏IResolutionRoot.Get<IUnitOfWork>()背后的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