I've done a couple of projects in ASP.NET MVC and there is a topic that I haven't really seen covered anywhere. I wanted to get some other peoples' opinions on this.
What are some best practices for designing models? I've taken two approaches in the past: Should models represent distinct entities, or should you have domain specific (sub-domain specific? view specific?) models? The difference really being models representing distinct entities are used in more than one view where as the domain specific models are tied to specific views.
Consider the following: I have a User entity in my application. Should I have a single UserModel that I use in the Register view, the Show view, the Index view, etc., or would it be preferred to have a RegisterUserModel, a ShowUserModel, a ListUserModel, etc.?
I've used both patterns before. The up side of the domain specific models is that any validation logic applied via attributes can be different between views. The down side is you violate DRY and your models get pretty hairy -- even if you separate them in to namespaces. Conversely, using the single model-to-entity pattern leads to overly generic validation data (usually with regard to error messages) but you have a nice, tight model layer and converting between models and entities is a lot easier (less code).
What approach does SO prefer? Or is there an approach that I'm not even considering?
I like to create my data models and then create specific view models as I need them.
The Case for ViewModel
The ViewModel Pattern
When I think of domain models, I think about business logic as well. I try to keep the M in MVC to refer to the models that assist in the presentation aspect of the application, and not the entities (domain objects) that represent my real-world objects.
Model and View shuld be a pair. Building huge Model classes and huge Views is not good idea. In my opinion in your view-Model you should represent only needed part of your business logic. For example. When you'r creating Registration form make your Model and View that simple as it can be possible - Create RegisterUserModel.cs and RegisterUserView.aspx. Do not pass there whole User object. Make it light, don't break Single Responibility Principle.
Related
I am looking to implement the Onion Architecture into our ASP.NET MVC application. I understand the need to separate View Models from Domain Entities, however I am finding myself writing redundant code. There is redundant code because my view models and domain entities look exactly the same with the exception that my view models have the [Serializable] data annotation. I need these models serializable because I am using ASP.NET Session State in which the State Server needs objects to be serializable.
I personally feel the domain entities should NOT be serializable because it would then become dependent on a particular technology. However, how can I avoid redundant code?
I should add that my service methods are dependent on these serializable data models.
I would avoid annotating my domain objects with anything persistence or non-domain related. This way, my Domain project wouldn't depend on another layer and I won't have it cluttered with things that aren't relevant to the Domain. While we need to bend the rules, I prefer bending them in a way not involving dependency on a persistence detail.
The point is to keep the layers focused on their purpose because it's very easy to mix'em up and create (in time) the big ball of mud.
In your case, I have the feeling you don't really have a rich domain or it's improperly modeled. It seems you only have data structures and your needs are CRUDy.
If you are certain the app won't evolve to become more complex i.e it will be just data structure manipulations then you can have one model to use them for all the purposes. Basically you can cut corners and use the 'business' model for everything. No need for abstractions and other stuff.
But if you think the app will evolve or they are or will be business rules and processes i.e you'll need to model behaviour as perceived by the business, then it's best to keep things very decoupled, even if at this stage they seem to be identical.
To make it easier, for your view model you can define one (with copy paste) and use automapper to map the business object to the view model one. Other approach maybe that your query service/repository/object could return directly that view model (map the query result to the view model)
Viewmodels can contain domain entities/models. My domain entities are partial classes and all (eventually) inherit from a base entity which is serialized. Since I use my domain models within some of my viewmodels, I use data annotations on the domain models as well. Your domain model library should not depend on/reference anything else (domain driven).
I wouldn't call [Serializable] a data annotation per se, since it's part of the core .Net platform (mscorlib.dll). Data Annotations refers to specific attributes used to perform data validation and other operations in ASP.Net or Entity Framework.
Should an Entity be [Serializable] ? Probably not, but I don't think this attribute is as "adulterating" to your domain layer as other attributes that come from external, web- or persistence-oriented libraries. It doesn't tie you to a particular third-party framework.
The whole "redundant code" issue depends IMO on the type of system you're building. In a genuine DDD application, duplication between Domain entities and View Models will probably not be all that blatant, and the benefits of a separate presentation model will typically outweigh the costs. A good article on that subject : Is Layering Worth The Mapping ?
So my programming background is very self-taught and sporadic. I am working on an MVC4 project and am trying to focus on best practices rather than just functionality.
The general sense of the project is a report generator. So I am trying to understand what exactly Domain Model vs View Model are, and how they related to the models used for CodeFirst Entity Framework. Any tips are appreciated.
From my understanding, let's say my Report object has multiple properties, but for the view I only want a user to be able to edit certain properties, then the ViewModel would be something that maps between the Report object and the user input?
Sounds like you've got the right idea. A ViewModel is the View representation of the domain entity. This can be applied to both data coming in and data going out of the model.
But, the extra layer (and mappings) also increase complexity of the code. You now need a view model class, a mapper class, and a domain entity (EF). So, if you can build what you need without this extra layer, then keep it simple. Domain models and domain modeling should only be used for a business domain that is significantly complex.
Yes your understanding is correct.
View model is data object used by your view. It contains properties necessary either for showing some data to user or collecting data from user. Those properties doesn't necessarily be only data. For example you can have some properties used to control if any field in the input form will be enabled or disabled.
Domain model on the other hand is object used for your logic and persistence. Again it doesn't necessarily contain only persisted properties. There can be other properties computed from persisted properties and there can be also methods working on top of properties.
In some very simple scenarios view model and domain model can be represented by the same object.
This is what I've seen in a few examples, what I've used for the last couple years and feel comfortable with, and was also the pattern already in use by a preexisting MVC team when I came into my most recent job.
Basically entity framework, or whatever ORM your using, will have Entity classes. These are either simple POCO's or something heavier with some ORM's. The goal is for the relationships between entities to closely resemble reality, and as such they are in a way your "Domain models". Either way, you will often find that you're view needs to either flatten properties from child/parent objects, or as you mentioned, only display certain fields.
Often times you will also need additional fields on the view model. For example, the options for a dropdown list, as these aren't part of the entity(only the foreign key that indicates which item is selected is in the entity, but not the list of items from which the user can select).
So unless your view is simple enough to be able to use the #model of your EF entity, often times you may need a ViewModel(VM) class. Some people have a different VM for each view. I personally try to reuse my VMs. Usually a PersonSummaryViewModel which is just a few fields good for things like select lists or indexes where space is limited and I will only display important fields, and a PersonViewModel which are all the fields from the entity, as well as fields for items for dropdown lists(but when used on a readonly page those are simply left null).
Personally I like to name things PersonVM and PersonSummaryVM but others prefer more verbose naming of PersonViewModel. EF will give your entities names like Person, but I've seen other ORM frameworks suffix all of the classes with Entity so you have PersonEntity. I've come to be fond of the Entity suffix personally.
If your database is well designed, it is likely that your entity classes are pretty close to what some would consider your domain model.
We have classes that expose static methods which we call to retrieve data. The controllers have little to no database code in them, and instead all of that are in static methods like PersonModelFactory.GetList(), PersonModelFactory.GetSingle(int id), .Save(PersonVM person) which are responsible for querying the database, and populating the data from the entities into the view models, and then returning a view model. These methods also perform certain validation(beyond what basic things you can do with data annotations on your view models), and other business logic IF it is something that should occur in tandem with whatever database modification is occurring. There's more to the implementation details involving interfaces and generic parameters that are aimed at making these methods very reusable but it is a little complicated for the scope of this post. We've actually successfully reused these classes from both web forms and MVC, so they've proved there re-usability. Some people wouldn't like the fact the DB access, mapping, and business logic/validation occurs in the same layer, but since the DB modification shouldn't occur unless validation passes, we felt it was important for these things to be atomic and mutually dependent.
It is probably more common for people to use the "repository pattern" for database access layer with MVC, and there are even scaffolding for MVC to generate these classes for you. However, these generally won't handle mapping or business logic.
Either way, the main goal is reuse and minimizing the clutter in your controller actions. Before adopting the factor pattern I mentioned, I found my controllers becoming cluttered. I saw opportunities for code to be reused between actions, and thus I was creating private methods in the controller. I really like the factory pattern the team I'm on now uses alot more.
You will definitely find many variations of how people use view models and repositories.
I cannot recall having seen any articles or examples that speak specifically about "domain models" in the context of MVC. IMO domain modelling is part of the requirements gathering process, and then the design of the database/entity framework will reflect the results of those findings. Given limitations of time/resources/complexity you may simplify the domain model. There are frameworks that deal with things like domain languages and what not, I don't think that kind of thing is very common.
Before there were ORMs, there were people doing alot of mapping manually between the database layer(consisting of command objects running SQL), into "business objects" which were often POCOs, basically what you have as EF entities, but sometimes they had some business validation/logic incorporated somehow. Now I don't hear people talk about "business objects" hardly ever because the purpose that layer served has mostly been replaced with EF, and the business logic is either in controller actions or in some other service layer.
Over the years, one thing is certain, what "view model", "business model", "entity", and "domain model" mean to different people will vary.
I noticed that I have views that need the same information like others. But sometimes you need 5 properties of the view model and sometimes only 2.
Do you share such view model over many views or do you create a separate view model for each view or maybe do you prefere an inheritance or composition strategy?
For me there are some disadvantages for sharing view models:
Principle of Least Surprise: It is strange to fill only 2 properties of 5 of a view model and get null reference exception, because you don't want to query additional data of the database. When the view model has 5 properties I expect that all are filled. The exceptions prove the rule.
Separation of Concerns/Single Responsibility Principle: The view model cluttered up on complex sites, because you have to suit different needs for each view. If logic is involved its getting more complex, too.
What do you think? How do you handle such circumstances?
People tend to have different philosophies of ViewModels based on their perspective of their use. ViewModels are the glue between a view and a model and people will typically base their answer on which of the two ends they like to hold more rigid.
If you like your model/data objects to be more rigid, then you'll tend to tie the ViewModel closer to the model/data—i.e. you'll have a single ViewModel that is used in multiple views and let the ViewModel determine which properties to retrieve based on how you want to handle data loading (and defer things like images or other long-load properties, etc.).
If you like your Views to be more rigid, then you'll tie the ViewModel closer to the View—i.e. have a separate ViewModel for each view and let the model/data objects handle things like syncronization as you move from view to view.
Personally, I prefer the first as my data tends to be more rigid because it's less likely to change than the views are (in my projects—I don't think that's a universal property of data and views). Since change notifications are a natural feature of ViewModels, I don't have to make my model objects communicate changes if a user happens to have two views up that show the same/similar data.
In the project I am working on, each view has its own ViewModel, however we also have CollectionViewModels, which are shared/referenced by multiple view models.
Think - a list of Suppliers, that needs to be displayed in multiple screens in your application - and is bound to a variety of controls - a list box, grid view, whatever you need. Having just one ViewModel makes for simpler update/refresh logic of the list of Suppliers.
TLDR: I would only reuse view models, if all usage cases use the ViewModel in the same way. I.e. they all use the same properties etc.
I would have a seperate ViewModel for each view. Unused properties make the code less readable (Why is that property present if it isn't being used?). If you have the same functionality for a fixed set of properties over several views I could see using a base class which contains those properties.
Definitely one ViewModel per View, imho.
As your application grows in complexity shared ViewModels will tend to grow, and it doesn't feel great to pass an object with 50 properties to a View when all it needs is one property.
Also, sometimes you may want to add extra properties in your ViewModel that are absolutely specific to your View and that you don't need in other Views. Say you have a CSS class that depends on properties from the ViewModel. Instead of writing if else statements in your View, you create a property in the ViewModel that returns the correct css class based on whatever business rules you have. This way you make the View as slim as possible and with a dedicated ViewModel you are not sharing a CSS class name with Views that don't really care about it.
I usually share ViewModels. As I understand it, the advantages of using view models are (a) security, in that properties that should be hidden are and (b) separation of concerns between business and presentation layers. (b) is accomplished just the same while sharing view models.
As for (a), I'm rarely in a situation where exposing a property is a security risk in one place but not in another. If a property needs to be hidden, it probably needs to be hidden everywhere. Of course, YMMV, but this seems like a fairly subjective question.
I use Entity Framework with Code First so my domain classes need to remain pretty rigid as they will be mapped to a sql database.
Some views use just one directly mapped entity and that's just great so I use the same domain layer entity. If that entity requires more information (two password fields for example) I will use composition. 'Composition should be favoured over inheritance', so if you can use composition do so, usually as it's just additional properties, composition can be used.
If there is a screen that uses only two properties of that entity, or I want to hide properties due to security concerns, I create a new view model and only retrieve the necessary data. I will reuse view models but only if the same properties are required in that other view.
I would share a VM between multiple view only if all properties variables and methods are used by all the views otherwise I would use inheritance and abstract base view model and if this does not solve. Do 1 to 1
TLDR: Yes (if you really want to use it and know how to use it wisely).
I can think of three responsibilities wanted from view model layer:
coupling view layer & model layer together
offering interface for unit testing
separating logic into small pieces when a single page is complex
The first responsibility actually conflicts with the second.
Because once a view model knows (couples with) the view class to initiate,
it cannot be unit tested.
Knowing the model (and its provider) class to initiate doesn't cause this problem.
However if the provider is a singleton, the unit test become less "unit".
When comes to the third responsibility, there is a kind of logic that I call them routing.
For example, after clicking on a button, the user should see the next page.
Which layer is this kind logic supposed to lie in?
View? Model? Definitely NOT!
It has no where to go but view model.
Once a view model knows the class of the view model of the next page to initiate,
it makes a giant view model tree to be dealt with.
Because this happen recursively – the next page also knows the next next page.
No matter on which node in this view model tree,
once a change happens,
it reflects on the parent nodes.
How to deal with these reflections?
Subclassing?
Remember, in the tree, a node can have hundreds of direct / indirect child nodes.
Conclusion – view model is good at the third responsibility only if it drops the first.
The only one it is really good at is the second responsibility.
However, I see nobody mentioning it under this question.
I have seen lots of tutorials and examples using Model-View UI design patterns, and they all implement them pretty differently, especially the Model part. In some examples Model is data (actual object representation of some DB) in some it's data access layer (like repository pattern) in some it's service layer...
If someone tells you he is using MV* pattern in his app, what will it tell you about app design? Does it maintain in-memory representation of database in object graph and use it as data source or some data access layer to query data base...
What you will choose as a Model for data oriented smart client app containing mostly Tab Pages with Tables?
The word model is used in, at least, two senses. There is your domain model. Here the sense is how you represent your data. There are many ways to structure your data and also many ways to access it. When we talk about the model in this sense we're not particularly concerned with how you are accessing the structures that make it up, i.e., the data access or persistence layer, although you may also hear people speak of the model of persistence. By this, people mean the particular philosophy that the persistence implementation uses, such as ActiveRecord or Repository. You might also hear these referred to as patterns.
Finally, the word model has a very specific meaning in MVC, MVP, and MVVM in the context of a view. In that context it means that particular data object associated with a view, the view model. This could be one of your domain objects, but more typically it is a view-specific object that encapsulates data from one or more domain objects along with ancillary data such as user data that is used by a particular view.
For your application, choose the persistence model that best suits your development environment and language -- LINQ to SQL, LINQ to Entities, nHibernate, Castle ActiveRecord, etc. in the MS world Create view-specific models (classes) for each of your views that hold the data needed by that view. Use your controllers to query your domain model to extract the information needed by the view and map that onto the view model.
If someone says, he is using MV* pattern, it means the application is split into several parts, acting without a direct reference to a specific type, it doesn't say anything about the actual implementation. MVVM means, you have a Model, a ViewModel and View part, that's all.
The model is your data storage. This doesn't say anything of the implementation of it, it can be anything, depending on the task at hand. However, it should be accessed using interfaces, so you can quickly exchange the implementation. That, in a sense, is the whole point of the MVVM pattern - decoupling of the three tiers via interfaces.
Your description sounds alot like my project at the moment - I use sqlite as backing storage with Entity Framework as ORM. However, I also use T4 to generate Dto objects which then get mapped via automapper in the ViewModel, as those only need the data, not the persistance.
The model typically refers to the data layer, but as I discovered, in MVC this can be a little msleading when implementing an ntier approach. The reason for this is that the model is not contained in it's own assembly.
Here is some of very useful feedback I got to a similar question Confussion over MVC and entity model
A model can be considered as data container that facilitates rendering presentation component and/or persisting data to/from data source (i.e. database etc). Besides the data container elements, a model may or may not contain behavior, depending on design context of corresponding architecture.
While the term “Model” is frequently discussed and used in Model-View-Controller pattern context, it is one of most important consideration in current world of software architecture
You may want to look the following article where few popular and new design patterns that are related to presentation component and model are described.
I am just figuring out best practice with MVC now I have a project where we have chosen to use it in anger.
My question is.
If creating a list view which is bound to an IEnumerable is this bad practise?
Would it be better to seperate the code generated by the WCF Service reference into a datastructure which essentially holds the same data but abstracts further from the service, meaning that the UI is totally unaware of the service implementation beneath.
or do people just bind to the proxy object types and have done with it ?
My personal feeling is to create an abstraction by creating a model and placing the Collection in that and referring to the collection in the UI code from the model.
but this seems to violate the DRY principle with respect to proxies.
Well, the best practice is to use a View Model which is populated from the Model. In many cases they could be the same because the view shows all the properties returned by the service, but another view could show only a subset of them. That's why having a view model is considered a good practice. This view model can also contain some calculated properties that are specific to the view. To further simplify the mapping between those objects you could use AutoMapper. There's also a nice article you may take a look at explaining the concept of view models.