I have an MVC ASP.NET project and I currently use a static ViewModelHelper class which has several methods (1 for each view model) that take in certain parameters and model objects and generate the view model objects for me to return to my views from my controllers. They are currently all static and the class as a whole is stateless, I just use it when I want to instantiate an instance of the view models because some of the data requires rather complex logic.
Would these methods be better off as constructors in the View Model classes? My understanding was it is better not to have any logic in the View Models, but I could be wrong. Or is there perhaps a design pattern I should be using here to help me create these View Models?
It's a question of your project's architecture and design how your ViewModels should look like and where/how they should be initialized. It seems that right now your ViewModels are DTOs and you initialize them with a factory approach. That is fine, but I'd suggest to actually embrace the abstract factory pattern then and make sure that the factory implementation doesn't get overloaded with unrelated responsibilities. That is an inherit problem of "utility" classes that should make every developer wary.
On the other hand, view-related initialization logic, e.g. populating select lists, can very well be located in the ViewModels themselves. In that case you should be wary of duplication.
Another possible approach would be to utilize a builder pattern.
Either way can be a clean solution if you use it exclusively and not mix and match. And as long as you keep it clean, of course. ;)
Without having seen that rather complex logic, I'd suggest you check why the initialization logic is that complex to begin with, though. And if it really has to be. Maybe some business logic snuck in there?
Your ViewModels should be just DTOs, classes with properties only. No logic. Put logic in other classes (services or full business logic, depends) and have them populate the ViewModel.
I'm aware to the fact that this answer seems very short relative to the substantial design consideration, but that's the core of it. For reasoning etc. please have a look at some full-fledge ASP.NET MVC solutions that demonstrate it, like https://prodinner.codeplex.com/.
Related
If I have a Viewmodel designed to serve a purpose for a view -
Is it a good practice to add bunch of static methods to the viewmodel like
- getting a list of items(viewmodel object) by consuming data from db?
- updating the db using a property in the viewmodel?
I am using .NET MVC and feel like my viewmodels get cluttered with bunch of static functions and update methods.
The main reason behind creating viewmodel for the views was because the views started to contain a lot of functionalities for which info had to be fetched from all over the place. So instead, i decided to create a viewmodel to get the info from one place with one call.
Am I following a good coding pattern here? Or am I shooting in the dark?
Is it a good practice to add bunch of static methods to the viewmodel
No, your viewmodel should simply be a POCO, containing as little (if not zero) business logic. A view models only job is to move data from the controller to the view.
Generally:
The controller should obtain an instance of a model from somewhere
this can be consumed by the view directly or if multiple models needs
combining or extra information (not in a model per se) is required
then a view model can be created.
Ideally the view model should be created outside of the controller
(keeping the controllers job clean), this can be achived simply by
using a factory pattern
If you read the wikipedia page for the MVC pattern. You'll notice it is solely designed for the presentation of data, not business logic:
Model–view–controller (MVC) is a software architectural pattern for
implementing user interfaces.
so really none of the MVC objects (Model, View or controller) should contain business logic. The MVC patterns job is to render data (full stop)
That all said it is common to put simple business logic into the controller. Once sites get more complex, though, this should be avoided, for fear of creating a god object
Am I following a good coding pattern here?
No, it's not a good pattern.
The main reason behind creating viewmodel for the views was because the views started to contain a lot of functionalities for which info had to be fetched from all over the place. So instead, i decided to create a viewmodel to get the info from one place with one call.
Store functionalities or any kind of logic is not the ViewModel's purpose. It should be just a transport mechanism that holds the data transported between the View and the Controller.
Consider move your "funcionalities" to Application, Service or another layer that makes sense for your application's architecture.
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.
I am using MVP to structure a project in C#. I previously had a IModel interface which contained CRUD operations, but have since split it into a number of Model interfaces (e.g. INotebookModel, ICategoryModel, IItemModel etc.) which each contain CRUD operations.
Would it be better to have an overall model which has CRUD methods that delegate to the appropriate specific models (e.g. create(String type)) or just holds references to each specific model in the presenter?
If having multiple models is a bad way to do it, how can I pass down the appropriate parameters so the model objects can be created/updated? As each object requires different information.
Having different models is not a bad way to do it.
This will surely make your design more complex but certainly increase your app's maintainability.
If you're building an app that needs to be evolutionary in future upgrades, then seperate your Model into several Models. This will help you in case you want to add a different entity into your app.
Maybe your books will be assigned to persons, then you will add a IPersonModel interface and the three other interfaces (INotebookModel, ICategoryModel, IItemModel) will remain intact.
However, if your application is simple and you want to favour rapid developement just centralize your model into one big Model. But be careful, if your app gets bigger, this model gets more and more complex since it will handle nearly all the app's responsabilities and you will have to explode it into many several ones.
So seperate your responsabilities, it is one of the SOLIDs. You can go further and take a look at this: http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
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've been reading too much probably and am suffering from some information overload. So I would appreciate some explicit guidance.
From what I've gathered, I can use VS2010's T4 template thingy to generate POCO classes that aren't tied directly to the EF. I would place these in their own project while my DAL would have an ObjectContext-derived class, right?
Once I have these classes, is it acceptable practice to use them in the UI layer? That is, say one of the generated classes is BookInfo that holds stuff about books for a public library (Title, edition, pages, summary etc.).
My BLL would contain a class BooksBLL for example like so:
public class BooksBLL
{
ObjectContext _context;
public void AddBook(BookInfo book) { ... }
public void DeleteBook(int bookID) { ... }
public void UpdateBook(int bookID, BookInfo newBook) { ... }
//Advanced search taking possibly all fields into consideration
public List<BookInfo> ResolveSearch(Func<BookInfo, bool> filter) { ... }
//etc...
}
So, my ViewModels in my MVVM UI app will be communicating with the above BLL class and exchanging BookInfo instances. Is that okay?
Furthermore, MVVM posts on the Web suggest implementing IDataErrorInfo for validation purposes. Is it okay if I implement said interface on the generated POCO class? I see from samples that those generated POCO classes contain all virtual properties and stuf and I hope adding my own logic would be okay?
If it makes any difference, at present, my app does not use WCF (or any networking stuff).
Also, if you see something terribly wrong with the way I'm trying to build my BLL, please feel free to offer help in that area too.
Update (Additional info as requested):
I'm trying to create a library automation application. It is not network based at present.
I am thinking about having layers as follows:
A project consisting of generated POCO classes (BookInfo, Author, Member, Publisher, Contact etc.)
A project with the ObjectContext-derived class (DAL?)
A Business Logic Layer with classes like the one I mentioned above (BooksBLL, AuthorsBLL etc)
A WPF UI layer using the MVVM pattern. (Hence my sub-question about IDataErrorInfo implementation).
So I'm wondering about stuff like using an instance of BooksBLL in a ViewModel class, calling ResolveSearch() on it to obtain a List<BookInfo> and presenting it... that is, using the POCO classes everywhere.
Or should I have additional classes that mirror the POCO classes exposed from my BLL?
If any more detail is needed, please ask.
What you're doing is basically the Repository pattern, for which Entity Framework and POCO are a great fit.
So, my ViewModels in my MVVM UI app will be communicating with the above BLL class and exchanging BookInfo instances. Is that okay?
That's exactly what POCO objects are for; there's no difference between the classes that are generated and how you would write them by hand. It's your ObjectContext that encapsulates all the logic around persisting any changes back to the database, and that's not directly exposed to your UI.
I'm not personally familiar with IDataErrorInfo but if right now your entities will only be used in this single app, I don't see any reason not to put it directly in the generated classes. Adding it to the T4 template would be ideal if that's possible, it would save you having to code it by hand for every class if the error messages follow any logical pattern.
Also, if you see something terribly wrong with the way I'm trying to build my BLL, please feel free to offer help in that area too.
This isn't terribly wrong by any means, but if you plan to write unit tests against your BLL (which I would recommend), you will want to change your ObjectContext member to IObjectContext. That way you can substitute any class implementing the IObjectContext interface at runtime (such as your actual ObjectContext), which will allow you to do testing against an in-memory (i.e. mocked) context and not have to hit the database.
Similarly, think about replacing your List<BookInfo> with an interface of some kind such as IList<BookInfo> or IBindingList<BookInfo> or the lowest common denominator IEnumerable<BookInfo>. That way you're not tied directly to the specific class List<T> and if your needs change over time, which tends to happen, it will reduce the refactoring necessary to replace your List<BookInfo> with something else, assuming whatever you're replacing it with implements the interface you've chosen.
You don't need to do anything in particular... as Mark said, there is no "right" answer. However, if your application is simple enough that you would simply be duplicating your classes (e.g. BookInfoUI & BookInfoBLL), then I'd recommend just using the business classes. The extra layer wouldn't serve a purpose, and so it shouldn't exist. Eric Evans in DDD even recommends putting all your logic in the UI layer if you app is simple and has very little business logic.
To make the distinction, the application layer should have classes that model what happens within the application, and the domain layer should have classes that model what happens in the domain. For example, if you have a search page, your UI layer might retrieve a list of BookSearchResult objects from a BookSearchService in the application layer, which would use the domain to pull a list of BookInfo.
Answers to your questions may depend on the size and complexity of your application. So I am afraid there will be valid arguments to answer your questions with Yes and No as well.
Personally I will answer your two main questions both with Yes:
Is it acceptable practice to use POCO (Domain) classes in the UI layer?
I guess with "UI layer" you don't actually mean the View part of the MVVM pattern but the ViewModels. (Most MVVM specialists would argue against letting a View directly reference the Model at all, I believe.)
It is not unusual to wrap a POCO from your Domain project as a property into a ViewModel and to bind this wrapped POCO directly to the View. The big Pro is: It's easy. You don't need additional ViewModel classes or replicated properties in a ViewModel and then copy those properties between the objects.
However, if you are using WPF you must take into account that the binding engine will directly write into your POCO properties if you bind them to a View. This might not always be what you want, especially if you are working with attached and change-tracked entities in a WPF form. You have to think about cancellation scenarios or how you restore properties after a cancellation which have been changed by the binding engine.
In my current project I am working with detached entities: I load the POCO from the data layer, detach it from context, dispose the context and then work with that copy in the ViewModel and bind it to the View. Updating in the data layer happens by creating a new context, loading the original entity from the DB by ID and then updating the properties from the changed POCO which was bound to the View. So the problem of unwished changes of an attached entity disappears with this approach. But there are also downsides to work with detached entites (updating is more complex for instance).
Is it okay if I implement the IDataErrorInfo interface on the generated POCO class?
If you bind your POCO entities to a View (through a wrapping ViewModel) it is not only OK but you even must implement IDataErrorInfo on the POCO class if you want to leverage the built-in property validation of the WPF binding engine. Although this interface is mainly used together with UI technologies it is part of System.ComponentModel namespace and therefore not directly tied to any UI namespaces. Basically IDataErrorInfo is only a simple contract which supports reporting of the object's state which also might be useful outside of a UI context.
The same is true for the INotifyPropertyChanged interface which you also would need to implement on your POCO classes if you bind them directly to a View.
I often see opinions which would disagree with me for several architectural reasons. But none of those opinions argue that another approach is easier. If you strictly would want to avoid to have POCO model classes in your ViewModel layer, you need to add another mapping layer with additional complexity and programming and maintenance effort. So I would vote: Keep it simple as long as you do not have a convincing reason and clear benefit to make your architecture more complex.