Entity Framework 4 and Repository Pattern
Could someone explain the benefits of using this pattern?
I mean isn't EF a repository in a sense already? Can't you just query the container and return those objects?
I see a lot of talk about POCO's, AutoMapper, Dependency Injection, Service L开发者_运维百科ayers, IoC. Am I just mixing a bunch of stuff together, or does it all relate?
Can someone explain this to me?
Also, how does this all fit together with MVC.net, ViewModels vs DataModels?
Thanks, Sam
There is a bunch of random question's there, so i'll give a bunch of random answers:
- A repository is defined (by Martin Fowler) as "Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects"
- EF is an ORM, which is the data mapping layer
- Yes, you can query the EF container and return the objects, but then the consumer "knows too much" about the underlying persistence mechanism, when it shouldn't know/care - hence the Repository pattern
- POCO's are a technique used to free your objects from persistence meta data (used by default EF code gen). They also allow your POCO's to double as your domain models.
- ViewModels are used by MVC Views.
- AutoMapper is used to translate ViewModels into Domain Models with ease.
- Service Layers provide a middle-ground between Controllers and the Repository - used specifically with
IQueryable<T>
Repositories, to materialize queries into concrete sequences (e.gICollection<T>
). - IoC is used to de-couple dependencies between components, which gives a good/clean architecture and supreme testability (you can pass through a Mock repository to your Controllers, to unit test them in an isolated fashion).
Elaboration Requested on #3
Example Controller WITHOUT Repository:
public class ProductsController
{
public ActionResult GetProduct(int productId)
{
Product p;
using (var ctx = new MySecretContextWhichIsNowExposed())
{
p = ctx.Products.SingleOrDefault(x => x.ProductId == productId);
}
return View(p);
}
}
Problems with the above:
- The Controller is working directly with an Entity Framework Object Context, which means the Web Application knows about it, and will need a reference to System.Data.Entity.
- Unit Testing is virtually impossible. You'll be testing against the actual database which makes it an integration test and not a unit test.
- The Controller has the logic of "how to retrieve a single product", when it shouldn't - this is domain/repository logic.
Example Controller WITH Repository (and IoC):
public class ProductsController
{
private readonly IProductsRepository _repo;
public ProductsController(IProductsRepository repo)
{
_repo = repo;
}
public ActionResult GetProduct(int productId)
{
Product p = _repo.FindById(productId);
return View(p);
}
}
Why above is better:
- Controller has no idea about EF. No dependency on System.Data.Entity.
- Controller doesn't know about the implementation of the Repository, it's working via an interface.
- Controller doesn't supply logic on how to retrieve the product, only the id.
- 2 lines of simple code.
- Unit of Testing = piece of cake. Pass through a
MockProductRepository
in the ctor, and work off that (which could be implemented as an in-memory list).
精彩评论