使用温莎城堡意味着 ISession 有时会被多次处置

发布于 2024-10-21 14:32:44 字数 1446 浏览 1 评论 0原文

我的所有存储库接口(即由用于将实体持久保存到数据库的类实现)都依赖于名为 IUnitOfWork 的接口。存储库类和 IUnitOfWork 由 Castle Windsor 处理,并具有 PerWebRequest 的生活方式。

Repository 实现(由所有存储库扩展)如下所示:

public abstract class Repository<T> where T : Entity
{
  protected IUnitOfWork _unitOfWork;

  internal Repository(IUnitOfWork unitOfWork)
  {
    _unitOfWork = unitOfWork;
  }

  public T Load(int id)
  {
    T t;
    t = _unitOfWork.Load<T>(id);
    return t;
  }

  public virtual void Save(T t)
  {
    _unitOfWork.Save(t);
  }

  public virtual void Delete(T t)
  {
    _unitOfWork.Delete(t);
  }

  public IQueryable<T> All
  {
    get { return _unitOfWork.GetList<T>(); }
  }
}

实现 IUnitOfWork 的类使用 NHibernate(它包含一个 ISession) 并有一个像这样的 Dispose 方法:

public void Dispose()
{
  _session.Flush();
  _session.Dispose();
}

因此,实体的保存遵循以下步骤:

  1. 从 DI 容器检索存储库(注入了 IUnitOfWork
  2. 通过加载实体存储库的 Load 方法
  3. 实体修改
  4. 通过存储库的 Save 方法保存的实体
  5. 在 Web 请求结束时由 DI 容器处理的存储库和 IUnitOfWork - 更改刷新到数据库

My问题是我偶尔会收到“会话已关闭!”的消息。对象名称:来自 NHibernate 的“ISession”错误。

据我所知,ISession 唯一被释放的地方是调用 IUnitOfWorkDispose() 方法时,即仅由 DI 容器调用。

谁能想到我可能会收到此错误的任何其他原因吗?

All my repository interfaces (i.e. implemented by classes for persisting entities to the database) have a dependency on an interface called IUnitOfWork. The repository classes and the IUnitOfWork are handled by Castle Windsor and have a lifestyle of PerWebRequest.

The Repository<T> implementation (which is extended by all repositories) looks like this:

public abstract class Repository<T> where T : Entity
{
  protected IUnitOfWork _unitOfWork;

  internal Repository(IUnitOfWork unitOfWork)
  {
    _unitOfWork = unitOfWork;
  }

  public T Load(int id)
  {
    T t;
    t = _unitOfWork.Load<T>(id);
    return t;
  }

  public virtual void Save(T t)
  {
    _unitOfWork.Save(t);
  }

  public virtual void Delete(T t)
  {
    _unitOfWork.Delete(t);
  }

  public IQueryable<T> All
  {
    get { return _unitOfWork.GetList<T>(); }
  }
}

The class which implements IUnitOfWork uses NHibernate (it contains an ISession) and has a Dispose method like this:

public void Dispose()
{
  _session.Flush();
  _session.Dispose();
}

Thus, the saving of an entity follows the following steps:

  1. Repository retrieved from DI container (with IUnitOfWork injected in)
  2. Entity loaded through repository's Load method
  3. Entity modified
  4. Entity saved through repository's Save method
  5. Repository and IUnitOfWork disposed by DI container at end of web request - changes flushed to database

My problem is that I am occasionally getting the 'Session is closed! Object name: 'ISession' error from NHibernate.

So far as I can see, the only place the ISession is disposed is when the IUnitOfWork's Dispose() method is called, which is only called by the DI container.

Can anyone think of any other reason I could be getting this error?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

Saygoodbye 2024-10-28 14:32:44

当您在某处出现异常,或者您尝试在代码中的某处调用自己的 Dispose 时,可能会发生这种情况。

Windsor 保证代码只会执行一次。

作为旁注 - 为什么需要 IUnitOfWork?它不会增加任何价值。

That probably happens when you have an exception somewhere, or you're trying to call Dispose yourself in the code somewhere.

Windsor guarantees that the code will be only executed once.

As a sidenote - why do you need the IUnitOfWork? It doesn't add any value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文