I have a View where I am searching my db for an object(i.e. Books)..
My controller for this view depends on a BooksRepository that implements a search method.
Everything works fine. I also have the option to do an advanced search which presents a larger form in a Modal popup. This form has many fields including a Dropdown box to select an 'Author' to search by.
I would like to pass a list of authors in my viewmodel so in my conroller I instantiate an instance of my view model, I need to call a repository method to bring back the list of authors's...
My thinking is that this GetAuthors() method should be in an AuthorRepository...
Is it bad practice to inject multiple repo's into a controller? or should I have an Author controller that gets injected with the author repo...and call a method in the Author controller from my BookSearch controller?
I think it's perfectly fine to refer to multiple repositories in a controller. A controller's job is to wrap data in a model and pass it to a view, regardless of how it gets to the data. Doing cross-controller calls can get messy.
I don't think it's a bad idea to inject the two repositories you need into the controller. Actually it sounds like a good practice.
But if you feel things are going out of hands, you might want to create an Application Service that would orchestrate a function in which you could inject several repositories. That would also be a way to move logic away from the controller.
But in this case, I think you are doing it right.
Read this book: http://www.infoq.com/minibooks/domain-driven-design-quickly
Personally, I would think that books and authors are pretty specific entities.... unless you're planning on having an author write a song as well, and you want to have a music repository and a book repository, I would probably keep the authors and books in the same repository, as you're more than likely going to need them both at the same time.
Even then, you could have a music repository and a book repository that both pull from the same author table. There's nothing wrong with that. And no, having more than one repository in a controller is not a "no-no", but unless you're using dependency injection, it can start to get hairy as you add more repositories.
I have a few controllers that reference more than one repository. Just be careful if each of your repositories instantiate their own data context (or EF ObjectContext). Speaking in terms of Entity Framework, if you start navigating entity references with two open contexts you'll have problems.
Other than that, it works fine for me.
From an architect point of view.
If you feel your mvc controllers are getting out of hand with dependencies, then its time to think about 2 things.
have a look at the design and determine if you need facade classes to represent complex subsystems, besides its better for unit testing anyway (there are such thing as 4 tier apps)
look at some of the other design patterns that can help solve this issue before it becomes it becomes a problem (strategy with DI, visitor possibly)
Also, I bet in this situation the unit tests are more of a pain, if you can't unit test it in a simple way, it should be flagged for improvement
Good luck,
Related
Is it correct to create Unit of Work in order to share the DbContext among the Repositories?
If isn't what is the recommendation? I really think it is needed to share the DbContext sometimes.
I'm asking this because of the answer for this question: In-memory database doesn't save data
Is it correct to create Unit of Work in order to share the DbContext among the Repositories?
It is design decision, but yes. There is no problem in doing that. It is absolutely valid that code from multiple repositories is executed under one single connection.
I really think it is needed to share the DbContext sometimes.
Absolutely; there are many times when you need to share DbContext.
Your linked answer is really good. I specially like the three points it mention. OP on that question is doing some unnecessary complicated things like Singleton, Service Locator and Async calls without understanding how they work. All these are good things but only if they are used at right time at right place.
Following is from your linked answer:
The best thing is that all of these could be avoided if people stopped attempting to create a Unit of Work + Repository pattern over yet another Unit of Work and Repository. Entity Framework Core already implements these:
Yes; this is true. But even so, repository and UoW may be helpful in some cases. This is design decision based on business needs. I have explained this in my answers below:
https://stackoverflow.com/a/49850950/5779732
https://stackoverflow.com/a/50877329/5779732
Using ORM directly in calling code has following issues:
It makes code little more complicated.
Database code is merged in business logic.
As many ORM objects are used in-line in calling code, it is very hard to unit test the code.
All those issues could be overcome by creating Concrete Repositories in Data Access Layer. DAL should expose concrete repositories to calling code (BLL or Services or Controller whatever) through interfaces. This way, your database and ORM code is fully consumed in DAL and you can easily unit-test calling code by mocking repositories. Refer this article explaining benefit of repository even with ORMs.
Apart from all above, one other issue generally discussed is "What if we decide to change ORM in future". This is entirely false in my personal understanding. It happens very rarely and in most cases, should not be considered while design.
I recommend avoid overthinking and over-design. Focus on your business objectives.
Refer this example code to understand how to inject UoW in repositories. The code sample is with Dapper. But overall design may still useful to you.
What you need is a class that contains multiple repositories and creates a UoW. Then, when you have a use case in which you need to use multiple repositories with shared UoW, this class creates it and pass it to repositories.
I typically call this class Service, but I think there is not some standardized naming.
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.
Currently in my application and using the unit of work pattern and generic repository, all my controllers contain all of the business logic. I'm in the process of putting everything over to use ViewModels instead of the straight Model.
While this is a good idea, now comes a question that can significantly separate my business logic in the controllers. For controllers and ViewModels, which should contain most of the business logic?
I've tried a few ways to get my ViewModels to practically contain all the business logic. However, I do have to have an argument in my ViewModel's constructor that takes a Unit of Work. Is this a good idea?
My code smell tells me it is. However, I am just a little worried how this will be in consistency with controllers that perform actions that do not need ViewModels. Simply put, actions that do not require to pass a Model/ViewModel to a View; this case happens on actions that do redirects to other actions. Which means, my business logic can either stay in that action or I could separate that business logic into a function.
What is the best practice here?
I can't say that my approach is a best practice, but I prefer to put any business logic in a separate "service" layer.
I tend to use the ViewModel to only store the properties required for a specific view. If there are any methods on the ViewModel, they are likely just to retrieve collections related to that view.
I keep my controllers lightweight by trying to limit them to validation and redirection/displaying views as much as possible.
So if I have any complex logic, I'll have a controller action call out to a separate service just to handle that logic. This way the logic is isolated which makes it easier to test since there's no longer a need to create a controller or ViewModel to test it. It's also easier to reuse a service than to pick apart a ViewModel.
Hopefully this helps. Good luck.
For controllers and ViewModels, which should contain most of the business logic?
None of those.
I've tried a few ways to get my ViewModels to practically contain all the business logic. However, I do have to have an argument in my ViewModel's constructor that takes a Unit of Work. Is this a good idea?
imho It's a very bad idea. First of all you are breaking several of the SOLID principles. Bundling all code into the view model makes it hard to test. What if you want to use some of the business logic in another view? Do you duplicate that code?
What is the best practice here?
Let's go back to the MVC pattern first. It's a quite wide definition but knowing it should give you a feeling of what you should place where.
The "Model" in MVC is really everything that is used to pull the data together. It can be webservices, a business layer, repositories etc.
The view is all code that generates the HTML (since we are talking about web).
The controller should be considered to be a glue between the model and the view. Hence it should take the information from the Model and transform it into something usable by the view.
The problem with that structure is that it's quite easy to "leak" layer specific information into the other parts of the pattern. Hence Microsoft introduced ViewModels into their implementation of MVC.
In this way we can remove all rendering logic from the views and put it into the ViewModel. Instead of doing this in your view:
<span>#(model.Age == 0 ? "n/a" : model.Age)</span>
you put that code inside the ViewModel instead and simply call #model.Age. In this way you don't have to duplicate that code in all views that are using your view model.
The answer to your question about the ViewModel is that it should only contain logic which is used to render the information from the "Model" properly.
As for the controller, I would not put any business logic into it either. First of all, it makes it very hard to test your logic. Then you add more responsibilities to it (and by doing so breaking SRP). The only logic that is valid in the controller is to take the information from the ViewModel and transform it into something usable by the "Model" and vice versa.
Hope that answers your question.
Update
I would create a separate project and add classes to it. Then just add a reference from your webproject and call those classes in the controllers.
I would also start using an inversion of control container to get those dependencies created for me automagically.
Autofac can both discover your services for you (zero-configuration) and inject itself into MVC.
To follow the separated interface pattern create the following projects:
YourProject.BusinessLayer <-- Add your classes here
YourProject.BusinessLayer.Specification <-- Add you interfaces that defines your business layer here.
YourProject.Mvc <-- The MVC project.
The "Specification" project can be used to make it easier to test things and to make it easier to switch implementation (might be only a few classes and not necessarily the entire business layer). Read up on "Seperated Interface Pattern"
Model-View-View Model (MVVM) is a design pattern for building user interfaces. Your View Model is a pure-code representation of the data and operations on a UI. Thus it should contain logic related to that UI.
For example:
if you’re implementing a list editor, your view model would be an object holding a list of items, and exposing methods to add and remove items.
From Wikipedia:
ViewModel: the ViewModel is a “Model of the View” meaning it is an
abstraction of the View that also serves in data binding between the
View and the Model. It could be seen as a specialized aspect of what
would be a Controller (in the MVC pattern) that acts as a data
binder/converter that changes Model information into View information
and passes commands from the View into the Model. The ViewModel
exposes public properties, commands, and abstractions. The ViewModel
has been likened to a conceptual state of the data as opposed to the
real state of the data in the Model.[7]
your controller call the UoW to get the data needed to construct your viewmodel.
you may call more than 1 method of your UoW
then you pass all your needed data to your viewmodel constructor. (passing the Uow to de viewmodel sounds like really bad)
If you need some complex 'logic' on your controller calling lot of methods from the UoW, etc, you should consider creating another repository or a business logic only layer that does all the hard work and you call it from your controller like
SomeClass something = Uow.BLGoodName.DoSomeFancyStuff(params ..)
ViewData.model = new ControllerActionViewModel(something);
Return View();
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've been using MVC frameworks for a short while now and I really like how the concerns are separated out. I've got into a bad habit of letting the controllers do quite a bit of work. So I'm really looking for some advice.
When I first started using MVC I quite often had the controller doing manipulation on the models after database work had been done. I knew this was bad so moved that work into the models. However I'm not happy with that as I want my models to be very learn.
I've done a bit of reading and I see that people are keeping their controllers and models lean by having a service layer, which I like the look of.
I'm just trying to understand how a service layer and repository should all work together. Here are my assumptions, can you please let me know if this is a good way of working?
The controller can call the repository directly if no manipulation needs to be done on the data and as such a service layer does not need to get involved
Once any work needs to be done to data (business logic) then this should be done in the service layer and the controller will make a simple call to the service layer as and when required
Once a service has done it's business logic it will then use the repository as necessary (if data needs to be persisted).
Models ideally should be kept lean, ideally actings as nothing more than DTOs
Validation of data will be done within the models (using MonoRail validation attributes). I appreciate not even one likes polluting their models with lots of attributes, but that is a different discussion. I like the benefit of MonoRail's validation attributes for the automatic jQuery validation in the UI.
I'm trying to turn all my code around to the single responsibility principle, hence trying to sort out my coding practices.
Thanks
First, there is no set of rules that's going to work in every situation. How you model you're application depends a lot on the type and complexity of the project. Having said that, here are some ideas:
Nothing wrong with calling the repository from a controller. Just make sure the controller does not contain business logic.
The service takes care of (some) business logic and uses other services to do so. The repository is a type of service, there's nothing wrong with calling it from a service.
The model should contain business logic, actually you should always try to put it in the model first. If you need external data to perform that business logic (from another model or from the repository) then you should create a service.
Nothing wrong with validation in the models. Using attributes or not is a question of taste (if you like it then it's good). Move the validation outside of the model if it gets too complex (create a external set of rules).
Most important, do what feels right (that's usually the right answer).
This video gives great insight into how to organize your asp.net MVC solution and addressing separation of concerns, and better testability. Hopefully it will help someone else also. I learned some good stuff from it.
Ian Cooper has just written a blog post called The Fat Controller on just this subject.