I\'m having a little bit of trouble conceptualizing how to architect an MVC App with Entity Framework into a n-tiered app.
The normal, textbook 3-tiered app should l
You can think of your EF entities as data objects, and have separate view-models that are passed into the views. Data from your EF objects can be used to populate the view models (libraries like AutoMapper are useful here). This way, your views never have a direct dependency on EF objects, only on your view-models.
I can recommend you really good (I think) book about domain driven architecture design on .NET platform. Book si called N-layered domain driven architecture guid with .NET 4.0. In book is explained how to create good architecture with EF and MVC (and many other stuff like Silverlight, IoC with Unity etc.).
Book can be downloaded on this address:
http://msdn.microsoft.com/es-es/architecture/en/
Also sample application is very interesting:
http://microsoftnlayerapp.codeplex.com/
Best way how to create entities for EF is creating POCO classes independent on persistent layer. These domain entities are included in Domain (Business) logic layer.
In book is also explained that application should be devided into more layers, they explaining Presentation, Appliaction, Domain, Infrastructure (data persistence mostly), Cross-cutting and Distributed services layers.
Well, I suppose your question is, how to architect "layers" in MVC application. Take a look at this simple architecture, I use it for my MVC apps and it seems to be clean and efficient.
project in solution - business model - simple class library full of POCO classes representing business domain. You can use data annotation here, metadata classes for validation logic, etc.
project - EF-based repositories - another simple class library; here is defined context (EF code first is great, but you can use EF database first or model first - you just have to add POCO T4 template to the business model class library, no big deal) and set of classes - repositories
project - i usually call it "ServiceLayer" or so (i am open for suggestion for better name :) - it contains only interfaces, for repositories and other services (implemented in separate projects) which will my MVC (or any other technology) based application use; repositories from 2.project implement these interfaces
project - MVC website. It uses dependency injection (build in DependencyResolver, and i love to use Ninject container) for mapping repositories (and other services); Then you can use constructor injection into controllers, or some "lazy" approach (see below)
It looks something like this :
Skinny controller :
public class SomethingController : BaseController { public ActionResult DoSomething(SomeBusinessThing input) { if (ModelState.IsValid) { var result = CustomerRepository.DoSomeBusinessLogicAndPersistenceAndStuff(input); return View(result); // you can use AutoMapper here, if you dont want to use business object as viewmodels } } }
My repository "property" is inherited from my BaseController :
public class BaseController : Controller { // ... other stuff used by all (or multiple) controllers private ICustomerRepository _customerRepository; protected ICustomerRepository CustomerRepository { get { if (_customerRepository== null) _customerRepository= DependencyResolver.Current.GetService(); return _customerRepository; } } }
You can use this "lazy" DI if your controller use many services, but only 1-2 per action, so it would be kind of inefficient to inject all of them with constructor. Somebody could tell you are "hiding" dependency this way, but if you keep all this stuff in one place - BaseController, its no big deal.
Well, implementation of repository is really your business. MVC application dont even know you are using EF, it knows only interfaces of services and doesnt care about underlaying implementation (which you can switch any time later if you need to !)
Conslusion :
Controllers are skinny - no business logic
Model is FAT - and in this case, repositories encapsulate all the business logic (you can sure use other type of services as well, for example some calculators for processing etc., remember, MVC doesnt care, knows only interfaces)
ViewModels are input for Views (and ViewModel can be your business model directly, or you can use AutoMapper for creating "pure" ViewModels)