nhibernate - 正确使用NHibernate工作单元模式和Ninject

标签 nhibernate session transactions ninject unit-of-work

我有以下实现,并希望获得一些关于它是否正确使用 NHibernate 进行 session 和事务的反馈。

public interface IUnitOfWork : IDisposable
{
    ISession CurrentSession { get; }
    void Commit();
    void Rollback();
}

public class UnitOfWork : IUnitOfWork
{
    private readonly ISessionFactory _sessionFactory;
    private readonly ITransaction _transaction;

    public UnitOfWork(ISessionFactory sessionFactory)
    {
        _sessionFactory = sessionFactory;
        CurrentSession = _sessionFactory.OpenSession();
        _transaction = CurrentSession.BeginTransaction();
    }

    public ISession CurrentSession { get; private set; }

    public void Dispose()
    {
        CurrentSession.Close();
        CurrentSession = null;
    }

    public void Commit()
    {
        _transaction.Commit();
    }

    public void Rollback()
    {
        if (_transaction.IsActive) _transaction.Rollback();
    }
}

Ninject 绑定(bind)

Bind<IUnitOfWork>().To<UnitOfWork>().InTransientScope();
Bind<ISessionFactory>().ToProvider<NHibernateSessionFactoryProvider>().InSingletonScope();
Bind<IRepository>().To<Repository>().InTransientScope();

这是一个用法示例:

public class Repository : IRepository
{
    private readonly ISessionFactory _sessionFactory;

    public Repository(ISessionFactory sessionFactory)
    {
        _sessionFactory = sessionFactory;
    }

    public void Add(IObj obj)
    {
        using (var unitOfWork = new UnitOfWork(_sessionFactory))
        {
            unitOfWork.CurrentSession.Save(obj);
            unitOfWork.Commit();
        }         
    }
}

在我之前的实现中,我会将 IUnitOfWork 注入(inject)到我的存储库构造函数中,如下所示

public Repository(IUnitOfWork unitOfWork)
    {...

但是 Dispose() 方法不会执行,导致后续调用抛出此异常:“无法访问已处置的对象。对象名称:'AdoTransaction'。”

最佳答案

第一个观察结果:您的存储库不应提交工作单元。这违背了工作单元模式的全部要点。通过立即将更改保存到存储库中,您可以“微观管理”NHibernate session 。

工作单元应该在堆栈的更高层(应用程序/服务层)中引用。这允许您让应用程序代码执行多个操作(可能在不同的存储库上),并且最终仍然一次提交所有内容。

UnitOfWork 类本身看起来不错,但您应该问问自己是否真的需要它。在 NHibernate 中,ISession 是您的工作单元。您的 UnitOfWork 类似乎没有增加很多值(value)(特别是因为您无论如何都暴露了 CurrentSession 属性)

但你确实需要考虑它的生命周期。我认为你在这一点上是错误的。 session 生命周期管理取决于您正在开发的应用程序的类型:在 Web 应用程序中,您通常希望每个请求都有一个工作单元(您可能需要在 google 上搜索“每个请求的 nhibernate session ”)。在桌面应用程序中,情况稍微复杂一些,大多数时候您需要“每个屏幕 session ”或“每个业务交易对话”。

关于nhibernate - 正确使用NHibernate工作单元模式和Ninject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4271265/

相关文章:

asp.net-mvc - 如何使用 ASP.NET MVC 2 在 NHibernate 上实现

c# - NHibernate:从所有数据库表中获取所有数据

MySQL Workbench 和默认 session 隔离级别

java - 无法反序列化 Spring Session Scoped bean

multithreading - 多线程应用程序中的 Berkeley DB

transactions - 区 block 链交易

c# - Fluent Nhibernate继承抛出索引超出范围异常

c# - 从文件设置 Fluent NHibernate 的指南 - 新项目

javascript - 将 javascript 添加到 drupal 无法识别某些 jquery

MySQL 在 TRANSACTION、COMMIT 和 ROLLBACK 上自动递增列