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 look something like
Data Access->Business Logic->Presentation
The presentation shouldn't know anything about the data access. With EF, ALL layers need to know about the model. So my architecture now looks more like
Data Access->Business Logic
| |
---------------
|
MVC
Am I missing something here or am I thinking about this in the wrong way?
Should I be thinking of EF itself as the data access layer and put the entities in the business logic?
Right-click the Controllers folder in Solution Explorer, select Add, and then click New Scaffolded Item. In the Add Scaffold dialog box, select MVC 5 Controller with views, using Entity Framework, and then choose Add.
Entity framework is an ORM (Object Relational Mapping) tool. Object Relational Mapping (ORM) is a technique of accessing a relational database; . i.e., whatever has tables and store procedure these things we interact with database in class, method and property of the object format.
You can use EF Core in APIs and applications that require the full . NET Framework, as well as those that target only the cross-platform .
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With