如何使用工作单元在Repository类中创建多个Repository对象?

时间:2012-06-04 14:41:20

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

我是MVC3应用程序开发的新手,目前,我们需要遵循以下应用程序技术

  1. MVC3框架
  2. IOC框架 - 动态管理对象创建的Autofac
  3. Moq - 单元测试
  4. 实体框架
  5. 模型类的存储库和工作单元模式
  6. 我已经阅读了很多文章来探讨关于上述观点的基本想法,但我仍然对“存储库和工作单元模式”感到困惑。基本上我理解的工作单元是一个模式,随后将与Repository Pattern一起使用,以便在所有Repository对象中共享单个DB Context,所以这是我的设计:

    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
    }
    

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

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

    因为,我想要创建的Repository对象我需要首先在PermitController类中实现UnitOfWork的对象。因此,如果我在每个单独的Repository类中遵循相同的内容,它将再次打破Unit Of Work的原则并创建多个对象上下文实例。

    所以任何想法或建议都将受到高度赞赏。

    谢谢

1 个答案:

答案 0 :(得分:1)

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

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

public interface IUnitOfWork
{
    int SaveChanges();
}

然后,您可以在Entity Framework 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接口不适用于此处。它适用于插入,更新和删除实体,而不是在选择实体时。