【问题标题】:How to create multiple Repository object inside a Repository class using Unit Of Work?如何使用工作单元在 Repository 类中创建多个 Repository 对象?
【发布时间】:2012-06-04 14:41:19
【问题描述】:

我是MVC3应用开发的新手,目前我们需要以下应用技术作为需求

  1. MVC3 框架
  2. IOC 框架 - Autofac 动态管理对象创建
  3. 起订量 - 单元测试
  4. 实体框架
  5. 模型类的存储库和工作单元模式

我已经阅读了很多文章来探索关于上述几点的基本概念,但我仍然对“存储库和工作单元模式”有些困惑。基本上我理解的工作单元是一种模式,它将与存储库模式一起遵循,以便在所有存储库对象之间共享单个数据库上下文,所以这是我的设计:

IUnitOfWork.cs

public interface IUnitOfWork : IDisposable
{
    IPermitRepository Permit_Repository{ get; }
    IRebateRepository Rebate_Repository { get; }
    IBuildingTypeRepository BuildingType_Repository { get; }
    IEEProjectRepository EEProject_Repository { get; }
    IRebateLookupRepository RebateLookup_Repository { get; }
    IEEProjectTypeRepository EEProjectType_Repository { get; }
    void Save();

}

UnitOfWork.cs

public class UnitOfWork : IUnitOfWork
{
    #region Private Members

    private readonly CEEPMSEntities context = new CEEPMSEntities();
    private IPermitRepository permit_Repository;
    private IRebateRepository rebate_Repository;
    private IBuildingTypeRepository buildingType_Repository;
    private IEEProjectRepository eeProject_Repository;
    private IRebateLookupRepository rebateLookup_Repository;
    private IEEProjectTypeRepository eeProjectType_Repository;

    #endregion

    #region IUnitOfWork Implemenation

    public IPermitRepository Permit_Repository
    {
        get
        {
            if (this.permit_Repository == null)
            {
                this.permit_Repository = new PermitRepository(context);
            }
            return permit_Repository;
        }
    }

    public IRebateRepository Rebate_Repository
    {
        get 
        {
            if (this.rebate_Repository == null)
            {
                this.rebate_Repository = new RebateRepository(context);
            }
            return rebate_Repository;
        }
    }

}

PermitRepository .cs

public class PermitRepository : IPermitRepository
{
  #region Private Members

  private CEEPMSEntities objectContext = null;
  private IObjectSet<Permit> objectSet = null;

  #endregion

  #region Constructors

  public PermitRepository()
  {
  }

  public PermitRepository(CEEPMSEntities _objectContext)
  {
      this.objectContext = _objectContext;
      this.objectSet = objectContext.CreateObjectSet<Permit>();
  }

  #endregion

  public IEnumerable<RebateViewModel> GetRebatesByPermitId(int _permitId)
  {
     // need to implment
  }

}

PermitController .cs

public class PermitController : Controller
{
    #region Private Members       
    IUnitOfWork CEEPMSContext = null;
    #endregion

    #region Constructors

    public PermitController(IUnitOfWork _CEEPMSContext)
    {
        if (_CEEPMSContext == null)
        {
            throw new ArgumentNullException("Object can not be null");
        }
        CEEPMSContext = _CEEPMSContext;
    }

    #endregion
}

所以在这里我想知道如何使用相同的模式生成一个新的存储库,例如“TestRepository.cs”,我可以在其中创建多个存储库对象,例如

RebateRepository rebateRepo = new RebateRepository ()
AddressRepository addressRepo  = new AddressRepository()

因为,无论我想创建什么 Repository 对象,我首先需要一个 UnitOfWork 对象,如 PermitController 类中所实现的那样。因此,如果我在每个单独的 Repository 类中遵循相同的做法,这将再次打破工作单元的原则并创建对象上下文的多个实例。

因此,任何想法或建议都将受到高度赞赏。

谢谢

【问题讨论】:

    标签: asp.net asp.net-mvc-3 repository-pattern unit-of-work


    【解决方案1】:

    你的IUnitOfWork 接口有太多的职责。每次添加新存储库时,都需要更改 IUnitOfWork 接口及其所有实现。

    相反,这样的事情怎么样?

    public interface IUnitOfWork
    {
        int SaveChanges();
    }
    

    然后您可以在您的实体框架 ObjectContext 或 DbContext 中实现此接口:

    public MyCustomContext : DbContext, IUnitOfWork
    {
        // ... this class already implements the SaveChanges method
    }
    

    然后您可以构造函数将工作单元注入您的每个存储库。 AutoFac 可以确保在同一个 HttpContext 中使用的多个存储库之间共享同一个实例:

    public class PermitRepository : IPermitRepository
    {
        #region Private Members
    
        private readonly IObjectSet<Permit> _objectSet;
        private readonly IUnitOfWork _unitOfWork;
    
        #endregion
    
        #region Constructors
    
        public PermitRepository(IUnitOfWork unitOfWork, IObjectSet<Permit> objectSet)
        {
              _unitOfWork = unitOfWork;
              _objectSet = objectSet;
        }
    
        #endregion
    
        public IEnumerable<RebateViewModel> GetRebatesByPermitId(int _permitId)
        {
           // need to implment
        }
    }
    

    然后,当您将存储库构造函数注入控制器时,IUnitOfWork 将自动被构造函数注入存储库。

    public class PermitController : Controller
    {
        #region Private Members       
        private readonly IPermitRepository _permitRepos;
        #endregion
    
        #region Constructors
    
        public PermitController(IPermitRepository permitRepos)
        {
            if (permitRepos== null)
            {
                throw new ArgumentNullException("permitRepos");
            }
            _permitRepos = permitRepos;
        }
    
        #endregion
    }
    

    请注意,从存储库中查询数据时,您实际上并没有做任何工作,因此 IUnitOfWork 接口不适用于此处。它适用于插入、更新和删除实体,而不是选择实体。

    【讨论】:

      猜你喜欢
      • 2021-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-28
      • 1970-01-01
      • 2020-12-23
      • 2018-03-02
      相关资源
      最近更新 更多