【问题标题】:Unit of work pattern - where to use?工作单元模式 - 在哪里使用?
【发布时间】:2012-02-09 07:47:53
【问题描述】:

我正在使用 ASP.NET MVC 3,并且正在使用 NHibernate 和 Ninject 的存储库和工作单元模式。我查看了几个示例(12)来帮助实施 UoW,但我只是不确定在哪里我应该使用工作单元。是否应该将其注入到我的控制器中,并在我的操作中手动调用 Commit 和 Rollback?

以下是一些代码示例:

工作单元(接口扩展 IDisposable 并具有 Session、Commit 和 Rollback)

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

    public UnitOfWork(ISessionFactory sessionFactory)
    {
        _sessionFactory = sessionFactory;
        Session = _sessionFactory.OpenSession();
        Session.FlushMode = FlushMode.Auto;
        _transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted);
    }

    public ISession Session { get; private set; }

    public void Commit()
    {
        if (!_transaction.IsActive)
        {
            throw new InvalidOperationException("No active transation");
        }

        _transaction.Commit();
    }

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

    public void Dispose()
    {
        if (Session.IsOpen)
            Session.Close();
    }
}

我的 Ninject 模块的一部分:

Bind<IXXXRepository>().To<XXXRepository>().InRequestScope();
Bind<IYYYRepository>().To<YYYRepository>().InRequestScope();
...

Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
Bind<ISessionFactory>().ToMethod(x => NHibernateHelper.CreateConfiguration(Path.Combine(
            HostingEnvironment.ApplicationPhysicalPath,
            "bin",
            "hibernate.cfg.xml")).BuildSessionFactory()).InSingletonScope();

Bind<ISession>().ToMethod(x => x.Kernel.Get<IUnitOfWork>().Session).InRequestScope();

我所有的存储库都继承自一个注入 ISession 的类,正如我在帖子前面所说的,我将 IUnitOfWork 注入我的控制器并在必要时调用 Commit 和 Rollback。我这样做对吗?我是否应该只在进行更新或删除时才调用 Commit,而不用担心调用它来进行选择?这会在每个请求结束时留下一个挂起的事务吗?

【问题讨论】:

    标签: nhibernate design-patterns ninject unit-of-work


    【解决方案1】:

    我喜欢在每个请求周围使用ActionFilter to automatically begin/commit the unit of work。这适用于我 95% 的操作。对于少数更复杂的,我将注入 UoW 并从控制器或服务显式管理它。

    我通常只是将 ISession 注入 UnitOfWork 以及存储库。存储库确实没有理由知道一个工作单元,它根本不应该触及事务。

    【讨论】:

    • 那么控制器是处理 UoW 的正确位置。每个请求是否应该只有一个 UoW?另外,如果在请求范围内既没有调用 Commit 也没有调用 Rollback 会发生什么,你是否留下了一个永远等待的挂起事务?
    • 好吧,如果你使用我上面链接的操作过滤器,它将确保每个事务要么提交要么回滚。有时我需要处理一个可能有多个提交阶段等的更复杂的过程,在这种情况下,我将决定在服务或控制器中处理 uow。通常情况下,我最终会将其放入服务中,以实现这样的复杂逻辑。
    • OK - 如果 Commit/Rollback 没有被调用,事务会无限期地保持打开状态吗?
    • 我认为它可能会保持打开状态,直到它被垃圾收集,但我不确定。确保它被明确地提交/回滚绝对是首选方法。
    • 好的,谢谢你的信息。我想我现在理解得更好了。
    猜你喜欢
    • 1970-01-01
    • 2017-02-24
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多