I am pretty new to MVC 4, and I have worked mostly with web forms up to this moment in C#. I understand the pattern of MVC, the routing, calling actions and so on.
But what about the actions which are responsible for fetching data from the database, for example by firing stored procedures? I have seen some tutorials where they put the logic for connecting to the database directly in the actions.
However I am thinking of a more centralized way to do it. For example, I can put all the functions which are firing stored procedures in a separate class named DatabaseCoordinator.cs in a folder named Helpers for example. Then I can call them from the actions in the controllers.
In that way I will know that I can find all of my methods for the database in one class, which is a very clean solution, I think (or at least in web forms). However I want to follow the pattern of MVC, and use only models, views and controllers as the name of the pattern itself implies.
So what is the best practice for that? Should I make a separate class for this, or implement the logic directly in the controllers, or perhaps somewhere else?
You should certainly make a separate repository class to contain all of your data access operations.
There is a good worked example here:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
I recommend that you put your data access code somewhere other than in your controller. The controller's primary purpose is to gather together the information for display on a page or the reverse - to take the data from the page that is posted back and feed it to the code responsible for business rules and data access.
For most MVC projects (heck, for most projects really!) I build separate class library projects - at minimum one for business rules and data access, though typically I'll make those two separate projects. The purpose of separating the logic is really for simpler future maintenance and reusability. If you keep your various logical parts separate, you can easily swap them out if your logic or database needs to change, or you can easily consume the business rules and data from a new type of user interface; for example, if you decided to implement your project as a Windows forms application in addition to your web system, you could (theoretically) just reuse your business logic and data access logic libraries and only rebuild the user layer. However, if you build your logic into your controller, you really can't reuse that logic without extracting it and converting it to the new application model you're using.
So, simply put, definitely keep 99% of your logic and data access out of your controller. Only put what you must put into your controller, the rest in a separate class, or where appropriate, in separate class libraries.
Good luck!
The Controllers and Views tend to stay within the same project, but it's common to split the data access classes and models into their own seperate class library, as this allows other projects to utilise them.
This will allow you, in the future, to maybe add a windows forms/wpf interface or maybe a mobile device interface, leveraging the work you already have in the standalone class library.
Another thing to consider, is looking into how to use ViewModels in your MVC application. It's a common technique when Views require more than one domain object. Using View Models in MVC.
Check out the Unit of Work Pattern (UOW) combined with the Repository Pattern. It doesn't matter if you ultimately call a stored procedure or an inline linq query to return results, your caller shouldn't know or care how GetPersons is ultimately implemented. The UOW pattern combined with the Repository pattern is a very popular way to expose an Entity Framework database in the ASP.NET community. You will find different ways to do it, some are over-kill and some just create dependencies with no actual benefit but you will find a way that feels right to you with those patterns.
After more experience, I would like to change my answer and state that the Repository Pattern and thus the Unit of Work pattern are pointless layers of abstraction to prevent you from working with Entity Framework, which is your data layer abstraction! directly.
Other than being able to swap out databases from say Microsoft SQL PostgreSQL (when would this ever happen in the real world?) and control the structure of complex queries that you don't want repeated in your code, I see no real value to the repository pattern. To include CreatedBy,ModifiedBy values on Insert/Update you need only override EntityFramework. To encapsulate queries that include business rules such as where active = 1 and isdeleted = 0 just extend Linq queries with extension methods.
Related
I want to know the right concept about it. If I have a MVC application with Repository Pattern, where the BL should be?
Should it be inside the Model? Model should have all the business
logic before call the unitofwork to insert or not the data into
database?
Should it be in the controller? Before call the model?
Should I have a service layer to do the business logic and decide if
I should call the Model to call the UnitOfWork to save the data?
A good explanation will help a lot too.
The short answer - it depends. If it's a fairly complex or sizable application, I like to create a service layer project with the repositories as dependencies. If it's a small application, I'll put the logic in the controller. In my opinion, if it takes more time and effort to create the service layer than it would be to create the application (i.e. one or two controllers), then it doesn't make sense to me to go that route. You also need to consider the likelihood that the application will grow. What might start small could grow into something much bigger and in that case, again, it might be more beneficial to create the separate service layer.
The third one... and then some.
Your application structure could look like this (each in different projects):
Data storage layer (e.g. SQL database)
ORM (e.g. NHibernate or Entity Framework)
Domain (including abstract repositories and entities)
Service layer (and optionally business)
MVC application (which has it's own models relating to the entities)
but there are many ways to go about this depending on the complexity and size of your application.
There is no "correct" answer to this question, it is primarily opinion-based. You can read about my opinion in the following project wiki:
https://github.com/danludwig/tripod/wiki/Why-Tripod%3F
https://github.com/danludwig/tripod/wiki/Dependency-and-Control-Inversion
https://github.com/danludwig/tripod/wiki/Tripod-101
https://github.com/danludwig/tripod/wiki/Testing,-Testing,-1-2-3
https://github.com/danludwig/tripod/wiki/Command-Query-Responsibility-Segregation-(CQRS)
Another piece of advice I would like to offer is never put any business logic in viewmodels or entities. These classes should not have methods, only properties to contain data. Separate your data from behavior. Use models for data, and other types for behavior (methods).
I have a project with the following structure:
Project.Domain
Contains all the domain objects
Project.EntityFramework, ref Project.Domain
Contains Entity Framework UnitOfWork
Project.Services, ref Project.Domain and Project.EntityFramework
Contains a list of Service classes that perform some operations on the Domain objects
Project.Web.Mvc, ref to all the projects above
I am trying to enforce some Business rules on top of the Domain objects:
For example, you cannot edit a domain object if it's parent is disabled, or, changing the name of an object, Category for example, needs to update recursively all it's children properties (avoiding / ignoring these rules will result in creating invalid objects)
In order to enforce these rules, i need hide all the public properties setters, making them as internal or private.
In order to do this, i need to move the Project.Services and Project.EntityFramework inside the Project.Domain project.
Is this wrong?
PS: i don't want to over complicate the project by adding IRepositories interfaces which would probably allow me to keep EntityFramework and Domain separate.
PS: i don't want to over complicate the project by adding IRepositories interfaces which would probably allow me to keep EntityFramework and Domain separate.
its really a bad idea, once i had this opinion but honestly if you dont program to abstraction it will become a pain when the project becomes larger. (a real pain)
IRepositories help you spread the job between different team members also. in addition to that you can write many helper extensions for Irepository to encapsulate Different Jobs for example
IReopisotry<File>.Upload()
you must be able to test each layer independently and tying them together will let you only do an integration tests with alot of bugs in lower layers :))
First, I think this question is really opinion based.
According to the Big Book the domain models must be separated from the data access. Your domain has nothing to with the manner of how storing the data. It can be a simple text file or a clustered mssql servers.
This choice must be decided based on the actual project. What is the size of the application?
The other huge question is: how many concurrent user use the db and how complex your business logic will be.
So if it's a complex project or presumably frequently modified or it has educational purposes then you should keep the domain and data access separated. And should define the repository interfaces in the domain model. Use some DI component (personally I like Ninject) and you should not reference the data access component in the services.
And of course you should create the test projects also using some moq tools to test the layers separately.
Yes this is wrong, if you are following Domain Driven Design, you should not compromise your architecture for the sake of doing less work. Your data-access and domain should be kept apart. I would strongly suggest that you implement the Repository pattern as it would allow you more flexibility in the long run.
There are of course to right answer to whats the right design...I would however argue that EF is you data layer abstraction, there is no way youre going to make anything thats more powerful and flexible with repositories.To avoid code repetition you can easily write extension methods (for IQueryable<>) for common tasks.Unit testing of the domain layer is easily handled by substituting you big DB with some in-proc DB (SqlLite / Sql Server Compact).IMHO with the maturity of current ORMs like nHibernate and EF is a huge waste of money and time to implement repositories for something as simple as DB access.
Blog post with a more detailed reply; http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer
Here is the situation :
I have an Asp.Net 3.5 website using a BLL project with object classes
containing methods which call a DAL which call stored procedures
(Oldschool)
I am creating a new website (Asp.Net 4 and MVC 3) using the same Database and objects. I will also add a bunch of classes and new tables (a dozen I guess) which are related to the existing classes and tables.
My probleme is :
How can I make all this working together. I really want to use MVC for the new project, and make all working as proper as I can.
The old project is a complete mess but it so huge that we can't touch it.
So how to handle the new object ? Use the same old method with classe and stored procedures ?
Create a repository pattern for the new object and classes ?
etc...
Thank you very much
ps : I don't know if I am clear but I can give you any other details if needed.
ps2 : I am not looking for coding solutions, but some indication of best method to follow for a smooth integration
I am currently finishing the DataAccess layer on a project with EXACT issues and this is how I have solved it:
I've used the repository pattern to insulate my "new code" from knowing anything about the old code. In the repository I use calls into the existing logic to generate any of the "legacy" entities and use Entity framework to manage any new ones. Some entities require a "combined" approach to the CRUD operations. For example when I create a new User entity I need to call two different objects from the legacy system, the first returns me a PIN that I use to call into another legacy object to create a user instance and return an Id and that Id is finally used with the new Entity framework to manage the "newUser" part of the object. This data access layer is then exposed to the MVC project that only knows about the entities as the new system sees them and have no idea what the underlying legacy structure is. As such our MVC project (and even business logic layer in our case) is only aware of repositories and if we decide to move the legacy logic/CRUD operations to the new system, nothing will change but the actual repository. This makes for some rather "bulky" repositories in some cases (most complex is the one I mentioned about users), but gives a clean separation of new and legacy code.
I know that this is injecting some business logic into the data access layer, but for our project this was a deliberate choice due to other factors. You can have your business logic layer make the calls into the legacy layer if you want to.
Hope this has helped, in case it is not clear just let me know and I will explain further as it might not be as clear here as it is in my head :)
You don't need to use the repository pattern, or EF, or DI, to use MVC. If your BLL is what you use to get your business objects (CRUD operations), there's no reason you can't use that directly in your controllers.
As far as adding new classes/tables, it depends on how tightly coupled your BLL is. If it's loosely coupled using interfaces it should be possible for you to use a different pattern for some DAOs, but if the DAOs reference each other directly it may be more trouble that it's worth.
If you want to go the extra mile I would say a good first step would be to define your CRUD operations in interfaces (if there are not interfaces already) and have yout BLL classes implement them so you can use DI and make it less painful when you do switch to a different DL strategy.
I think I've hit that "paralysis by analysis" state.
I have an MVC app, using EF as an ORM.
So I'm trying to decide on the best data access pattern, and so far I'm thinking putting all data access logic into controllers is the way to go.. but it kinda doesn't sound right.
Another option is creating an external repository, handling data interactions.
Here's my pros/cons:
If embedding data access to controllers, I will end up with code like this:
using (DbContext db = new DbContext())
{
User user = db.Users.Where(x=>x.Name == "Bob").Single();
user.Address.Street = "some st";
db.SaveChanges();
}
So with this, I get full benefits of lazy loading, I close connection right after I'm done, I'm flexible on where clause - all the niceties.
The con - I'm mixing a bunch of stuff in a single method - data checking, data access, UI interactions.
With Repository, I'm externalizing data access, and in theory can just replace repos if I decide to use ado.net or go with different database.
But, I don't see a good clean way to realize lazy loading, and how to control DbContext/connection life time.
Say, I have IRepository interface with CRUD methods, how would I load a List of addresses that belong to a given user ? Making methods like GetAddressListByUserId looks ugly, wrong,
and will make me to create a bunch of methods that are just as ugly, and make little sense when using ORM.
I'm sure this problem been solved like million times, and hope there's a solution somewhere..
And one more question on repository pattern - how do you deal with objects that are properties ? E.g. User has a list of addresses, how would you retrieve that list ? Create a repository for the address ? With ORM the address object doesn't have to have a reference back to user, nor Id field, with repo - it will have to have all that. More code, more exposed properties..
The approach you choose depends a lot on the type of project you are going to be working with. For small projects where a Rapid Application Development (RAD) approach is required, it might almost be OK to use your EF model directly in the MVC project and have data access in the controllers, but the more the project grows, the more messy it will become and you will start running into more and more problems. In case you want good design and maintainability, there are several different approaches, but in general you can stick to the following:
Keep your controllers and Views clean. Controllers should only control the application flow and not contain data access or even business logic. Views should only be used for presentation - give it a ViewModel and it will present it as Html (no business logic or calculations). A ViewModel per view is a pretty clean way of doing it.
A typical controller action would look like:
public ActionResult UpdateCompany(CompanyViewModel model)
{
if (ModelState.IsValid)
{
Company company = SomeCompanyViewModelHelper.
MapCompanyViewModelToDomainObject(model);
companyService.UpdateCompany(company);
return RedirectToRoute(/* Wherever you go after company is updated */);
}
// Return the same view with highlighted errors
return View(model);
}
Due to the aforementioned reasons, it is good to abstract your data access (testability, ease of switching the data provider or ORM or whatever, etc.). The Repository pattern is a good choice, but here you also get a few implementation options. There's always been a lot of discussion about generic/non-generic repositories, whether or not one should return IQueryables, etc. But eventually it's for you to choose.
Btw, why do you want lazy loading? As a rule, you know exactly what data you require for a specific view, so why would you choose to fetch it in a deferred way, thus making extra database calls, instead of eager loading everything you need in one call? Personally, I think it's okay to have multiple Get methods for fetching objects with or without children. E.g.
public class CompanyRepository
{
Get(int Id);
Get(string name);
GetWithEmployees(int id);
...
}
It might seem a bit overkill and you may choose a different approach, but as long as you have a pattern you follow, maintaining the code is much easier.
Personally I do it this way:
I have an abstract Domain layer, which has methods not just CRUD, but specialized methods, for example UsersManager.Authenticate(), etc. It inside uses data access logic, or data-access layer abstraction (depending on the level of abstraction I need to have).
It is always better to have an abstract dependency at least. Here are some pros of it:
you can replace one implementation with another at a later time.
you can unit test your controller when needed.
As of controller itself, let it have 2 constructors: one with an abstract domain access class (e.g. facade of domain), and another (empty) constructor which chooses the default implementation. This way your controller lives well during web application run-time (calling empty constructor) and during the unit-testing (with mock domain layer injected).
Also, to be able to easily switch to another domain at a later time, be sure to inject the domain creator, instead of domain itself. This way, localizing the domain layer construction to the domain creator, you can switch to another implementation at any time, by just reconstructing the domain creator (by creator I mean some kind of factory).
I hope this helps.
Addition:
I would not recommend having CRUD methods in domain layer, because this will become a nightmare whenever you rich the unit-testing phase, or even more, when you need to change the implementation to the new one at a later time.
It really comes down to where you want your code. If you need to have data access for an object you can put it behind an IRepository object or in the controller doesn't matter: you will still wind up with either a series of GetByXXX calls or the equivilent code. Either way you can lazy load and control the lifetime of the connection. So now you need to ask yourself: where do I want my code to live?
Personally, I would argue to get it out of the controller. By that I mean moving it to another layer. Probably using an IRespository type of pattern where you have a series of GetByXXX calls. Sure they are ugly. Wrong? I would argue otherwise. At least they are all contained within the same logical layer together rather than being scattered throughout the controllers where they are mixed in with validation code, etc.
I usually write use cases for all the software that I develop. For each use case I generally write a controller which directs the flow (implements a use case).
I have recently started developing web apps using Asp.net MVC. One of the best practices of Asp.net MVC is to keep very less logic in the controllers. I am not able to figure out how will I change my design to reflect this.
I basically want a way to encapsulate my use cases.
I think having a fat model and skinny controller is generally a good practice in any language and not specifically .NET MVC. Checkout this nice article that goes through a sample scenario showing the advantages of a fat mode in Ruby on Rails (but the ideas apply to any language).
For representing the use-cases in your code, I think a much better place for them is in test-cases rather than the controller.
Push as much business logic to your models and helper classes as possible, and use controllers mainly for handling URL calls and instantiating the relevant models, retrieving data from them, and pushing data to the views. Views and controllers should have as few decisions to make as possible.
Create a business component to encapsulate use cases. For instance if you have a leave management system you would have use cases like apply for a leave, approve a leave request, reject a leave request, etc. For this you can create a business component (class) called Leave Manager with methods (functions/operations) like "Apply", "Approve", "Reject", etc. These methods will encapsulate your use cases. These methods would take your business entities and data store classes as input and execute the use case.
class LeaveManager{
int Apply(from, to);
bool Approve(leaveApplicationId, approverId);
bool Reject(leaveApplicationId, approverId);
}
You can then use this business component in your controllers to execute the use case by supplying the required parameters.