工作单元和存储库模式

Chr*_*ris 12 c# design-patterns unit-of-work repository-pattern

我使用NHibernate设置了存储库模式.基类如下所示:

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

// generic NHibernate implementation of IUnitOfWork here

public class NHibernateRepositoryBase<T> : IRepository<T>
{
    private NHibernateUnitOfWork _unitOfWork;

    public NHibernateRepositoryBase(NHibernateUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }
    public T Get(object id)
    {
        return _unitOfWork.Session.Get<T>(id);
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我允许通过构造函数(使用StructureMap)填充工作单元.我正在填充ASP.NET Web服务上的存储库对象,如下所示:

[WebService(Namespace = "...")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class ModuleService : System.Web.Services.WebService
{
    public IUserAccountRepository UserAccountRepo { get; set; }

    public ModuleService()
    {
        // tell IoC to inject properties
        ObjectFactory.BuildUp(this);
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

正如你可以推断的那样,我的问题是,通过设计,我现在已经失去了对工作单元生命周期的控制.以前,我将工作单元作为上下文敏感对象,并且存储库将通过以下方式获取对它的引用:

public class NHibernateRepositoryBase<T> : IRepository<T>
{
    public T Get(object id)
    {
        return NHibernateUnitOfWork.GetCurrent().Session.Get<T>(id);
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

之前的设计允许我通过在using语句中创建UnitOfWorkFactory的工作单元来控制代码中工作单元的生命周期.我试图把更多的工作交给IoC容器,但我想我实际上倒了一步.您对这两种实施方式有何看法?

Mat*_*son 3

让 IoC 容器处理尽可能多的事情通常是一件好事。在网络上,工作单元模式通常在请求开始时初始化并在结束时提交(如果有任何异常则回滚)。这样,您的存储库将在构造函数中采用 ISession 而不是工作单元。这样,您的存储库将不必处理提交或任何其他事情,并且将自动为您处理。

  • NHibernate 会话本身基本上就是一个工作单元。将其隐藏在您自己的工作单元接口后面的原因基本上是这样您可以以通用方式将其公开给应用程序的其余部分(在您的存储库之外),而不依赖于 NHibernate。这主要是在请求开始时初始化它并在请求结束时提交它。 (3认同)