My simplest ASP.NET MVC 2 controllers make calls to my service layer and map view models to entities using AutoMapper. Everything looks fantastic and there is no repeated code.
However, when I get into scenarios where I have similar behavior I have trouble balancing Single Responsibility Principle (SRP) with Don't Repeat Yourself (DRY). An example of this might be the need to add/edit vehicles where some properties/behaviors are shared while others are unique to a specific vehicle.
If I strive for really thin controllers (thus honoring Single Responsibility Principle), I end up having repeated code in both the views and controllers with minor variations (title, field labels, field visibility, dropdown values, selection criteria, etc.).
If I strive for non-repeated code I end up bundling too much logic into a single controller/view and it gets bloated.
What are some ways of addressing repeated code in controllers / views? I'm not talking about database code that can be factored out to a repository. Nor am I talking about business logic that can be factored out to a service layer. I'm looking for tools and/or rules of thumb that will help me produce the best solution in the scenario described above.
You get:
partials
RenderAction
action filters
service layer and helper classes (not HtmlHelper)
model binders
base controllers
dependency injection
So your views can invoke shared partials/actions for similar parts, common data can be prepared by action filters, database access code can be hidden in smart model binder, or you can have parent controller that child controllers override with specific tweaks. And, of course, good old service layeres, where you just extract common code into helper/static methods, or, better, inject specific implementations.
That's nothing new, same old tricks.
Or, maybe, your controllers do too much works? This is where stuff above also helps. ASP.NET MVC has very good tools to hide infrastructure-layer code and move it away from controllers. And if it's not infrastructure - it probably belongs to domain layer. There you can use inheritance, composition and other OOP tricks.
Specific example. Suppose your controllers should set few properties in a different way.
You can have your views to do this, if it's mostly formatting or choosing what properties to show
You can have your entities to have virtual methods - i.e. refactor code to move decisions to domain layer instead of controllers
You can have helper ViewDetails classes that will take your entities and get the data based on for what you need it; this is a bit of a dirty trick but sometimes useful; you delegate decision to another "strategy" class
You can use action filters to add this data to ViewData, or to tweak specific ViewData.Model types (look for some interface of it).
You can have abstract controller, where children pass implementation details to the base constructor like (): base(repository => repository.GetSpecificData())
And so on. I actually use all of them in appropriate places.
You are worrying too much about SRP and DRY. They are principles only and are not always right. SRP and DRY are good if they make your code more maintainable, but if they are in the way then ignore them. MVC is similar. It is useful in simple small desktop applications but is not appropriate for web applications. Web Forms is much better for the internet world while MVC is something from the 1980s.
I recommend you to use SRP over DRY in those cases. I wrote here a detailed answer.
In short both are rules which help to keep your code maintainable. DRY is a low abstraction level mechanism, while SRP is a high abstraction level. By maintain an application the high abstraction level structure is more important than the low abstraction level.
In your case I don't think it is necessary to give up DRY.
An example of this might be the need to add/edit vehicles where some
properties/behaviors are shared while others are unique to a specific
vehicle.
Many design patterns can help in this case. You can use decorator, composition, and so on... combined with builders for the different types of vehicles.
I found that ApiEndpoints is very good for this. You create a class for each controller method. A little more code, but I think it's very clean.
Related
I'd like to create a good app in ASP.NET MVC 5 using EF 6 Code first concept. I want it to be well-designed i.e. having generally speaking: Presentation, Logic and Data layers separated. I want it to be testable :)
Here's my idea and some issues related with creating application
Presentation layer: It's my whole MVC - view models(not models), views, controllers
I believe that's validation should be done somewhere else (in my opinion - it's a part of business logic) but it's quite convenient to use attributes from the DataAnnotations namespace in ViewModelds and check validation in controller.
Logic layer: Services - classes with their interfaces to rule business logic.
I put there functions like: AddNewPerson(PersonViewModel Person), SendMessageToPerson(...).
They will use DB context to make their actions (there's a chance that not all of them will be relying on context). There's a direct connection between service and db - I mean the service class have reference do context.
Where should I do mapping between ViewModel and Model? I've heard that service is a bad place for it - so maybe in controllers. I've heard that service should do the work related with db exclusively.
Is it right? Is my picture of service layer is good?
Data layer: I've read about Repository and UoW patterns a lot. There're some articles which suggest that EF6 implements these two things. I don't want to create extra code if there's no need for such a behavior. The question is: am i right to assume that i don't need them?
Here's my flow:
View<->Controllers(using ViewModels)<->Services(using Models)<->DB.
**I'm gonna use DI in my project.
What do you think about my project structure?
There is no reason to use a Unit of Work pattern with Entity Framework if you have no need to create a generic data access mechanism. You would only do this if you were:
using a data access technology that did not natively support a Unit of work pattern (EF does)
Wanted to be able to swap out data providers sometime in the future.. however, this is not as easy as it might seem as it's very hard NOT to introduce dependencies on specific data technologies even when using an Unit of Work (maybe even BECAUSE you are)... or
You need to have a way of unifying disparate data sources into an atomic transaction.
If none of those are the case, you most likely don't need a custom Unit of Work. A Repository, on the other hand can be useful... but with EF6 many of the benefits of a Repository are also available since EF6 provides mocking interfaces for testing. Regardless, stay away from a generic repository unless it's simply an implementation detail of your concrete repositories. Exposing generic repositories to your other layers is a huge abstraction leak...
I always use a Repository/Service/Façade pattern though to create a separation between my data and business (and UI and business for that matter) layers. It provides a convenient way to mock without having to mock your data access itself and it decouples your logic from the specific that are introduced by the Linq layer used by EF (Linq is relatively generic, but there are things that are specific to EF), a façade/repository/server interface decouples that).
In general, you're on the right path... However, let me point out that using Data Attributes on your view models is a good thing. This centralizes your validation on your model, rather than making you put validation logic all over the place.
You're correct that you need validation in your business logic as well, but your mistake is the assumption that you should only have it on the business logic. You need validation at all layers of your application.. And in particular, your UI validation may have different requirements than your business logic validation.
For instance, you may implement creating a new account as a multi-step wizard in your UI, this would require different validation than your business layer because each step has only a subset of the validation of the total object. Or you might require that your mobile interface has different validation requirements from your web site (one might use a captcha, while the other might use a touch based human validation for instance).
Either way, it's important to keep in mind that validation is important both at the client, server, and various layers...
Ok, let’s clarify a few things...
The notion of ViewModel (or the actual wording of ViewModel) is something introduced by Microsoft Martin Fowler. In fact, a ViewModel is nothing more than a simple class.
In reality, your Views are strongly typed to classes. Period. To avoid confusion, the wording ViewModel came up to help people understand that
“this class, will be used by your View”
hence why we call them ViewModel.
In addition, although many books, articles and examples use the word ViewModel, let's not forget that it's nothing more than just a Model.
In fact, did you ever noticed why there is a Models folder inside an MVC application and not a ViewModels folder?
Also, ever noticed how at the top of a View you have #model directive and not # viewmodel directive?
That's because everything could be a model.
By the way, for clarity, you are more than welcomed to delete (or rename) the Models folder and create a new one called ViewModels if that helps.
Regardless of what you do, you’ll ultimately call #model and not #viewmodel at the top of your pages.
Another similar example would be DTO classes. DTO classes are nothing more than regular classes but they are suffixed with DTO to help people (programmers) differentiate between all the other classes (including View Models).
In a recent project I’ve worked on, that notion wasn’t fully grasped by the team so instead of having their Views strongly typed to Models, they would have their Views strongly typed to DTO classes. In theory and in practice everything was working but they soon found out that they had properties such as IsVisible inside their DTO’s when in fact; these kind of properties should belongs to your ViewModel classes since they are used for UI logic.
So far, I haven’t answered your question but I do have a similar post regarding a quick architecture. You can read the post here
Another thing I’d like to point out is that if and only if your Service Layer plans on servicing other things such as a Winform application, Mobile web site, etc...then your Service Layer should not be receiving ViewModels.
Your Service Layer should not have the notion of what is a ViewModel. It should only accept, receive, send, etc... POCO classes.
This means that from your Controller, inside your ActionResult, once the ModelState is Valid, you need to transform your ViewModel into a POCO which in turn, will be sent to the method inside your Service Layer.
In other words, I’d use/install the Automapper nugget package and create some extension methods that would convert a ViewModel into a POCO and vice-versa (POCO into a ViewModel).
This way, your AddNewPerson() method would receive a Person object for its parameter instead of receiving a PersonViewModel parameter.
Remember, this is only valid if and only if your Service Layer plans on servicing other things...
If that's not the case, then feel free to have your Service Layer receive, send, add, etc...ViewModels instead of POCOs. This is up to you and your team.
Remember, there are many ways to skin a cat.
Hope this helps.
I am facing a design issue with an mvc 3 app. I have a viewmodel ProductCreateModel that has a list of Categories.
Now I am setting the Categories list in the controller, but I am thinking if it is a good idea to indect the datasource in ProductCreateModel constructor.
Do you think that view models should be fat models that also know to read dependent data from the data source? ... or this is a controller thing?
I prefer slim viewmodels that do not know a thing about data layer. They are easier to manage (in my experience).
I think view models should be light models, and the only way for them to read related data, should be properties on "parent" object, the model they actually wrap.
Most of the time my view models are just classes with properties, all logic are in the controller or in a service class (if we're talking a lot of logic that would otherwise be put in the controller). All this is in the name of easier testing.
When I learned MVC I was taught that the "rule of thumb" is Skinny Controllers, Fat Models, Dumb Views. A mistake that many MVC developers make is Fat Controllers (too much logic), Skinny Models (basically POCO classes to hold data), and Smart Views (a bunch of Razor Syntax with If this, Else that, etc.)
Over the years I've stuck to the Skinny Controllers, Fat Models, Dumb views approach, and it has worked well for me. Now, take into consideration that this is related to Models and not ViewModels. Usually your Models should be in an entirely different layer (i.e. proj or folder). ViewModels, on the other hand, should be fairly simple. This makes them easier to test, and more reusable. If you are finding that you need some sort of service, repo, or other dependency to build up your ViewModels, then you should probably abstract that logic out into some sort of Composer Class. In the past I've used a ViewModelManager which implements IViewModelManager, to compose my ViewModels if need be. This way you can inject IViewModelManager into your controller, and use it to build your ViewModels. Then, in your ViewModelManager implementation, you can inject your other dependencies, like repos, services, etc. to actually construct your ViewModel.
This approach definitely requires more code, and many more classes, but it will give you a good level of granularity, and separation, plus support the DRY principle along with Single Responsibility.
Happy Coding!
As a general rule, I don't think you want to do that.
As an exception to that rule, I've started using a little bit of Service Locator in my Editor Templates when creating drop downs. I've gone through multiple ways of populating drop downs (generally, some form of adding a collection to either the view model or into view data). I saw a video where SL was used in the Editor Template to get the data and then convert to a Select List. My initial reaction was "ugh, really?", but, the more I thought about it, it made sense.
What pros and cons for:
Use BLL as model.
Model inherit BLL.
Model contain BLL.
Model has only fields that are going to be used by view.
Something else.
Background:
I have some heavy BLL class with about 100 fields. I'm going to show some of them in a view. How a related model should look.
No pros, only cons for all those approaches. The best approach is a combination of 4 and 5. It is called view models. So create a view model for each view which contains only the fields this view needs and map between your model and the view model. This mapping could be facilitated with a tool like AutoMapper.
First, let's make some assumptions clear.
The "ASP.NET MVC" is based upon a proven standard, known as the "Model-View-Controller" architectural pattern. This is not a new invention from some Microsoft geek; quite the opposite, this pattern has been used by several frameworks since 1979.
So, what is "the model"? Using a more modern term, it is the domain logic. It is your business entities, your data access objects, even some of your static declared enumerations and collections: anything that is used by your application, has business value and is not related to some specific presentation issue or requirement.
That's why I said your question, deep inside, does not make much sense.
After you tried to explain what your question is about, and after jim and Darin Dimitrov answers, I guess what you really need, what you are really asking about, became a little clearer: what you want to know is how to bind your existing, pre-MVC business layer with the C and the V of an ASP.NET MVC application.
So, if you do have a well designed BLL layer, and, more importantly, if your BLL and DAL communicate through some DTO's, you could, theoretically, bind them directly to your views.
If those DTO's need to be transformed in some way (because they could not be directly understood by the end user, for instance), this should be done by the use some "ViewModels", which are basically another set of presentation specific DTO's, plus data-annotations for server-side data validation. This transformation, of course, should be done by your controllers.
Some MS people will say that you MUST use viewmodels, and that if you don't use them you will rot in hell. I do not entirely agree. Of course, there are several advantages in using view models (like the already mentioned data-annotations, compile-time verification, intellisense and so forth), but if many other successful MVC frameworks are fine without them, I don't think it should be different with ASP.NET MVC.
That's my 2 cents.
Edit Another important advantage of using viewmodels is related to security: by exposing a set of presentation-only DTOs, the real domain-objects become somewhat protected.
Kamarey,
You can safely use your exisiting BLL (if it satisfies the business needs). You then simply need to identify the discreet sections in your views that you want to update and create ViewModels for those. You may find of course that there are some instances where you can strongly type your exisiting BLL model down to the view. i.e, e.g. etc..
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<IList<yourbll.model>>" %>
In short, i think you'll need to analyse the needs of the views in relation to your BLL.
take a look at this SO question for inspiration on the ViewModel:
ViewModel Best Practices
http://stephenwalther.com/blog/archive/2009/04/13/asp.net-mvc-tip-50-ndash-create-view-models.aspx
http://www.highoncoding.com/Articles/659_Implementing_ViewModel_in_ASP_NET_MVC_Application.aspx
I think the best approach is mostly a combination of 3 and 4, using whichever is easiest for a particular view.
Where the bll object is exactly what the view needs, you can use it directly. This doesn't come up much though, as you almost always need something else - values for a dropdown, names instead of ids, etc.
Where the data object is very close to the view, I have it as a property of the model object. That way my controller can jsut set model.DataObject instead of copying properties individually. On edit forms you need to be careful that your view contains fields for all the data object properties (obviously not a good choice if there are sensitive fields), but it is perfect for read only views.
For more complex views or those that don't really map well to a single data object, use a custom model object and copy the properties you need so you have complete control over what is included and can keep the view code simple.
I have tried using inheritance, but that really just gets you the worst features of all the other approaches.
It's also worth noting that you can quite easily switch to a different model if you need to - with strongly typed views any mismatches are easy to find and fix.
I'm new to developing web apps using ASP.NET MVC. In fact, I'm rather new to developing web apps, regardless of technology.
Currently, I'm working on a project just to get to know the ASP.NET MVC framework better. When reading on SO and elsewhere on the internet, the consensus seems to be that the views should never deal directly with the business objects (i.e. objects implementing business logic and containing associated attributes). Instead, view models should be used. However, this introduces a couple of issues:
Where do I put my validation code?
I need to add code to map between business objects and view models.
In fact, it seems rather cumbersome and I haven't really seen anyone explaining properly why it's a bad idea passing business objects to the views. Could someone please try to explain this (or point to a good explanation)?
Just a clarification; I'm not looking for examples on how to handle the two issues with view models above but simply an explanation on why I should use view models at all.
Where do I put my validation code?
On the view models you should validate everything that's specific to the application like for example the date should be in en-US format culture, ....
I need to add code to map between business objects and view models.
That's why there are tools such as AutoMapper.
Different problems arise when you use directly your domain models in the views:
The views have specific requirements for displaying the data (localization/globalization) so you either end up with spaghetti code in your views or you put this code on your models so that they become less reusable in other applications because you have polluted them with specific presentation stuff
You have different validation requirements based on the view. Let's take for example the case of Add and Update views. In the Add view the Id property won't be needed and it won't be required because you will be inserting a new item. In the Update view the Id property would be required because you would be updating an existing item. It would be difficult to handle those specific validation rules without view models.
The models might contain properties such as IsAdmin and then I am leaving to your imagination the implication of a controller action with the following signature:
[HttpPost]
public ActionResult CreateUser(BusinessObjectUser user) { ... }
assuming that you have hidden this property from the underlying form by not including it.
The business models don't change often whereas the UI could change more often. What if your customer asks you to split your screen in two? The way you present the information changes and the way it is formatted also change. If you use your models directly into the views the spaghetiness of your views becomes worse and worse with every change.
About 60% of the question I am answering on StackOverflow in the asp.net-mvc tag wouldn't have been asked if the OP have used a view model.
Three reasons to why you should use View Models:
Reason 1: Remove logic from your Views
Reason two: Security
Reason three: Loose coupling
Below link may useful:
http://www.codeproject.com/Articles/223547/Three-reasons-to-why-you-should-use-view-models
First off, allowing the Views to have direct access to the Business Objects in ASP.NET MVC introduces some extra security concerns. ASP.NET MVC does a lot of Model binding for you when a user posts a value back to your controller. This can open you up to various kinds of attacks. By introducing a View Model in between, you can be sure that only the fields you are interesting are bound (because the ViewModel will only contain the fields you care about).
As for the other questions:
Where do I put my validation code?
I use DataAnnotations on my ViewModels directly. That allows me to use the Model validation architecture built in to ASP.NET MVC. If there's any validation beyond that I handle it in my controller.
I need to add code to map between
business objects and view models.
True. But using something like AutoMapper can greatly reduce the amount of boilerplate code that you have to write by hand.
MVC is easy to understand and has very little overhead. But those that have used the Model-View-Controller pattern for some time know that it isn't perfect. Not even close. The Model-View-ViewModel pattern offers an interesting alternative.
It is important to understand that the Model-View-ViewModel pattern extends the Model-View-Controller pattern. It isn't a dramatic paradigm shift if you are used to MVC. Even though the advantages of MVVM are subtle, they are profound.
What are some of the advantages MVVM has over MVC?
Better Separation of Concerns
Improved Testability
Transparent Communication
To me, this seems to make little sense, but after reading the information in the following:
http://weblogs.asp.net/scottgu/archive/2010/02/05/asp-net-mvc-2-release-candidate-2-now-available.aspx
http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html
http://blog.stevensanderson.com/2010/02/19/partial-validation-in-aspnet-mvc-2/#comment-35397( specifically some of the comments)
It appears that the idea behind Asp.Net MVC is that you have a one-to-one relationship between models and views. This seems to go against the DRY principle and several other standard programming practices.
For example, lets say you have a user account model and there are two views available to edit it - one for the user himself to edit it and one for the site admin to edit it. The admin has access to an additional field for something internal, required but the user cannot view/edit it. Per the model binding functionality and the beliefs described in the posts referenced above, I would need to create two separate user models, one for each page, and the only difference would be that additional field. This is just a simple example as well, I've got a few that I've seen where it would potentially mean 5 or 6 different models for the exact same object, just a few fields different between each view. That really doesn't make any sense to me.
I did not read the posts you mentioned, but there is nothing wrong with having one Model for a couple of views.
I would just have this one UserModel and use it in all Views, even if there are some fields that are not used.
If things get a bit more complicated but Users still have a lot in common you can either use aggregation for the usermodel (User.Address) or use Interfaces (User has fields street , and city and implements IAddress).
Both methods have their pros and cons - with aggregation used in the majority of situations.
EDIT
After reading the posts I saw that they deal with validation. This is a different story.
If you want to use DataAnotations you have to have different classes if validation varies. I dont use DataAnnotations - so I guess your class design might be different.
If you're using annotations, I'd strongly consider one "model" and multiple "viewmodels." We went with a viewmodel approach on our current app and have been reaping the benefits, because our basic model needs to be shown in a couple different views.
There is no official requirement to have only one view per model in ASP.NET MVC. In many cases that would lead to duplication of code.
I personally like to split model-view dependencies, that is, one view per model. It comes down to the fact that you never know how, say, a couple of very similar model-view pairs are going to evolve in the future. If they're separate, you just introduce changes in one and you don't have to "fix" the other views that were dependent on this model, or worse, to take extra work to create own models for them all at once.
TL;DR: Make many view models. They are cheap and flexible.
"This seems to go against the DRY principle and several other standard programming practices."
[Citation Needed]?
MVC doesn't change the fact that in any language or pattern you need to make a view model definition for each separate screen. Whether via attributes, via XML, via toggling web form controls, whatever.
The DRY principal usually pertains to repeating business logic. Repeating a FirstName property across a CRUD screen section really isn't a big deal. Even 5-6 times, whats that? 40 seconds?
If you mistake your view models for object oriented classes and not homoiconisticish screen representations you run the risk of filling them up will all sorts of inheritance and or business logic.
Your not really programming when you make dumb view definitions. This work could easily be done in an Access GUI or defined in XML. The fact that your screen-view-models are in C# just makes it easier to fill them up with data and ship them around and work with tools like WCF and Automapper.