简体   繁体   中英

MVC 5 EF6 unit of work and repository pattern

How do you implement the unit of work and repository pattern in MVC 5 and EF6? Previously I've avoided any need for unit of work by using a single repository which was injected into my controller as follows:

public class ProductController : BaseController
{
    private IShopRepository _repository;


    public ClassController()
        : this(new ShopRepository())
    {
    }

    public ClassController(IShopRepository repository)
    {
        _repository = repository;
    }


    ....

}

But now I want to refactor the code so that I have a separate repository for each entity type eg. ProductRepository, CustomerRepository etc and be able to inject multiple repositories into a controller whilst ensuring the same dbcontext is used.

Reading through the microsoft tutorial on http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application , the architects now advise the repository and unit of work pattern are no longer needed but they don't provide any example of how to implement or structure repositories in their examples?

Some people have even started renaming repositories to services?

How do you structure your repositories and implement unit of work in MVC5 using EF6 perhaps using an IOC such as Unity? Or what is another solution?

I'm working along the following lines but not sure if it is best solution and how do i add unit of work?

public class ShopContext : DbContext
{
    public ShopContext() : base("name=ShopContext")
    {
    }

    public DbSet<Product> Products { get; set; }
    public DbSet<Customer> Customers { get; set; }
    ...

}


public interface IProductRepository
{
   IEnumerable<Product> GetAll();
   ...
}


public interface ICustomerRepository
{
   IEnumerable<Customer> GetAll();
   ...
}

public class ProductRepository : IDisposable, IProductRepository
{
     private ShopContext _context;

     public ProductRepository()
     {
    _context  = new ShopContext();

     }

     public IEnumerable<Product> GetAll()
     {
        return _context.Products;
     }

     // Other methods not displayed

     protected void Dispose(bool disposing)
     {
       if (disposing)
       {
           if (_context != null)
           {
              _context.Dispose();
              _context = null;
           }
       }
     }

     public void Dispose()
     {
       Dispose(true);
       GC.SuppressFinalize(this);
     }

}

public class CustomerRepository : IDisposable, ICustomerRepository
{
     private ShopContext _context;

     public CustomerRepository()
     {
        _context  = new ShopContext();

     }

     public IEnumerable<Customer> GetAll()
     {
        return _context.Customers;
     }

     // Other methods not displayed

     protected void Dispose(bool disposing)
     {
       if (disposing)
       {
           if (_context != null)
           {
              _context.Dispose();
              _context = null;
           }
       }
     }

     public void Dispose()
     {
       Dispose(true);
       GC.SuppressFinalize(this);
     }
}


public class ProductsController : BaseController
{

   private IProductRepository _productRepository;
   private ICustomerRepository _customerRepository;


   public ProductsController()
        : this(new ProductRepository(), new CustomerRepository())
    {
    }

   public ProductsController(IProductRepository productRepository, ICustomerRepository customerRepository)  
   {
       _productRepository = productRepository;
       _customerRepository = customerRepository;

   }

   // Other controller methods not shown.
} 

Example code would be helpful.

The best working example one can find is the series of Mr Mittal at codeproject he is using Entity Framework , Generic Repository pattern and Unit of Work . keep up with him you'll get to know how this all works here is the link Mittal Series

As @Thomas has already stated in the comments, I think what you're after here is a service layer rather than a repository. The two terms are often used very interchangeably, but they are not the same thing.

The repository pattern is intended to provide an abstraction of the database so that the database can change without impacting on the rest of the code. The DBContext in EF6 is already doing that for you as you can have, for example, a table called one thing, but mapped to a class with a different name. The DBContext also already implements the Unit of Work pattern, as it will perform all actions inside a single transaction up until you call SaveChanges / SaveChangesAsync on the context.

The service layer then provides methods to the user interface layer. It calls the methods from the repository to do this.

With a simple model it seems like the service layer and the repository are the same thing, but your repository would typically map to one business object (eg a Contact) where as your service layer might encapsulate a number of objects (eg a Customer business entity, which when saved stores data to the Contact and CustomerProfile repositories), using a unit of work to ensure that both changes are committed or rolled back together.

This excellent existing stack overflow answer by @ken2k goes into this in much more detail.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM