Santosh
Santosh

Reputation: 33

How to create multiple Repository object inside a Repository class using Unit Of Work?

I am newbie to MVC3 application development, currently, we need following Application technologies as requirement

  1. MVC3 framework
  2. IOC framework – Autofac to manage object creation dynamically
  3. Moq – Unit testing
  4. Entity Framework
  5. Repository and Unit Of Work Pattern of Model class

I have gone through many article to explore an basic idea about the above points but still I am little bit confused on the “Repository and Unit Of Work Pattern “. Basically what I understand Unit Of Work is a pattern which will be followed along with Repository Pattern in order to share the single DB Context among all Repository object, So here is my design :

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
}

So here I am wondering how to generate a new Repository for example “TestRepository.cs” using same pattern where I can create more then one Repository object like

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

because , what ever Repository object I want to create I need an object of UnitOfWork first as implmented in the PermitController class. So if I would follow the same in each individual Repository class that would again break the priciple of Unit Of Work and create multiple instance of object context.

So any idea or suggestion will be highly appreciated.

Thank you

Upvotes: 0

Views: 1194

Answers (1)

danludwig
danludwig

Reputation: 47375

Your IUnitOfWork interface has too many responsibilities. Each time you add a new repository, you would need to change your IUnitOfWork interface and all of its implementations.

Instead, how about something like this?

public interface IUnitOfWork
{
    int SaveChanges();
}

You can then implement this interface in your Entity Framework ObjectContext or DbContext:

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

You can then constructor inject the unit of work into each of your repositories. AutoFac can make certain the same instance is shared among multiple repositories used within the same 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
    }
}

Then, when you constructor inject the repository into the controller, the IUnitOfWork will automatically be constructor injected into the repository.

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
}

Note that when querying data out of your repository, you're really not doing any work, so the IUnitOfWork interface does not apply here. It applies when inserting, updating, and deleting entities, not when selecting them.

Upvotes: 1

Related Questions