ninject 仅创建一次 NHibernate UnitOfWork,每次后续实例化 return 上一个 UoW 关闭会话
ninject create NHibernate UnitOfWork only one time, every subsequent instantiation return previous UoW with closed session
我在我的 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 块一起使用时,return 该会话已关闭
这是我的 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 的新尝试 return 最后一次使用已处理的会话。
在尝试使用 ninject 之前,我所做的只是:
using (Iuow = new UnitOfWork())
{
....
}
一切正常
p.s。
我必须从绑定中删除 InRequestScope
,因为它甚至会阻止页面加载工作
替换
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
我在我的 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 块一起使用时,return 该会话已关闭
这是我的 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 的新尝试 return 最后一次使用已处理的会话。
在尝试使用 ninject 之前,我所做的只是:
using (Iuow = new UnitOfWork())
{
....
}
一切正常
p.s。
我必须从绑定中删除 InRequestScope
,因为它甚至会阻止页面加载工作
替换
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