I have separate library (Controls.DLL) with my custom Controls.
I have another library (Model.dll) with my data access code.
Some controls do need access to data. I'd like to keep those libraries loosely coupled. Basically, I'd like to acces data without referencing Model.dll
What is the proper way to do it? Naturally, I think Binding is a way to go. But it's not just binding to data, I also need to execute actions against my model (retreive data, paging, filtering). And I need to study metadata that my model contains.
For example, I have Customer class with properties like "FirstName", "LastName", etc. But I want those to be displayed inside my control with captions like "First Name", "Last Name". This is primitive example but it kind of shows my point.
My other idea was to have "providers" on data side that would spit out XML and on control side I will parse this XML. But how do I go about methods?
Another idea is to go with reflection. This way I would just pass object to Control. But I'm not as good with reflection and not sure if I can achieve things like: getting properties/attributes. Getting and executing methods? This sounds like a perfect thing to code with Interfaces but Interface need to live somewhere and therefore something have to reference something.
So, what is the best way to code loosely like this?
Check out the MVVM pattern (Model-View-ViewModel).
Basically, a ViewModel wraps a Model, and exposes data access and data manipulation commands to the user interface (the View) via property bindings.
You'll find heaps of documentation, tutorials etc. by searching for MVVM. Or check out this StackOverflow answer to get you started.
Update:
MVVM allows you to separate custom controls and data. It sounds like you want to dynamically generate interface components based upon data in your model. You can do this in MVVM (it's not the only way, of course). The view model can dynamically generate collections based upon the model. The view model can include methods for converting raw data to display data. This means neither your model or controls (view) need to know how to
do this.
Depending on the nature of your data, you may choose to have `generic' view models reflect over property names to procedurally generate display names (as in your primitive example), or you may choose to write specific view models for specific data in your model. That will depend upon the nature of your data. Either way, your custom controls (in the view) remain decoupled from the model.
Update 2:
Your view models do not need to live in the same assembly as the view (controls). You can even put them in a third assembly (as described here). Of course that encourages you to follow MVVM more strictly and make sure you have no dependencies from ViewModel to View, but that's a good thing. There are a few more hints on the issues related to hooking up views to view models you may encounter here.
Related
what goes where?
This is a short description of my C# project:
I have a mechanical construction (only one in the whole program), described by some 20 to 30 parameters (deimensions, material parameters etc.), that may, as a complete set, come from an input screen or from an XML file (Deserialized). These parameters must then be processed in a calculation to generate output, that goes to a JPEG file and also to an HTML file.
The View is clear: it's the IO screen.
The View needs an ViewModel where the Properties are. Maybe:
My Model is the construction at hand, that is described by its parameters.
Those parameters however, are the same ones that are gathered from the IO screen , the View or from XML.
Some output (the JPEG file) also goes the View. It might be a Property that Notifies it's changed.
Now my question is, do I need a Model at all, because the ViewModel has all the properties already.
Or, do I need a ViewModel at all, because my Model has all the Properties to be Viewed. I could define a Model in the ViewModel (like it is always done in MVVM) and use the Model as a DataContext for the View. But that last option would make the View aware of the Model: not in the MVVM spirit.
I've written this multiple times already, but I'll do it once more...
The main reasoning behind MVVM is to separate layers and to avoid tight coupling as much as possible.
That said, View is, as you've correctly guessed, the UI. Things your user sees. It doesn't matter if it's a Windows, a Page, a custom control, webpage or even a console (when we talk about MVVM in a broader context).
ViewModel is a mediator between your model and the view. It takes, combines and manipulates your methods and properties from the model for the purposes of the View. It doesn't care how, when and where are these used. It also can trigger actions on the model side, for instance call services that take care of updating your database.
Model is EVERYTHING that isn't tied to the specific platform. It's classes of your business logic, it's database entities etc. It's basically your application stripped of any ties to the UI implementation. This is what people get wrong and think that model are only database entities. That's simply wrong!
To answer the question you've asked: "Now my question is, do I need a Model at all, because the ViewModel has all the properties already."
Yes, you should, otherwise you'll end up coupling the view directly to the model and that's violating MVVM principle. Your View shouldn't know ANYTHING about the model directly. As far as View cares, every one of the properties and methods can be coming from a different project. It won't change a thing and the view will still function the same.
You maybe don't see it yet, but in the future it will make your life much more easier. The code becomes easily maintainable if done correctly, much more readable etc.
In addition of what #walter said, you can check this Codeproject entry which explains flawlessly the difference and a little bit more. That article helped me to undestand when I was beginning:
http://www.codeproject.com/Articles/100175/Model-View-ViewModel-MVVM-Explained
In short:
Model: A class that represents data, it shouldn't do anything. It's good practice to implement INotifyPropertyChanged, however it's not required if you don't need to change the data from the View.
ViewModel: A class that exposes the model as a public property so that the view can bind to it. It should contain methods that interact with the model. It could also contain properties of it's own.
View: Binds to the ViewModel, where it can access the model, and ViewModel properties.
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 viewmodel1 and viewmodel2.
Viewmodel1 needs to show data from a list of some sort contained in model.
Viewmodel2 needs to input data to the list contained in model.
So both Viewmodel1 and Viewmodel2 need to "know" about model.
What is the proper way to do this in MVVM?
Should I create model in app and give viewmodel1 and viewmodel2 a reference to it or?
I find it helps if I think of a ViewModel as being a Model, translated just for the View.
You have a few choices:
Create a controller which sets up the ViewModel. This is usually a good choice if the ViewModel needs information from more than one place. You can either give the ViewModel a reference to all the information it needs, or make it a Plain Old .NET Object (PONO) and have the controller set it up for you.
Just pass the reference to the ViewModel as you suggest. Useful if no interaction is required between different classes
Wire up the EventAggregator, which can be used to publish a notification when models change, and pass a Repository to the ViewModels so that each of them can go and get / store the model when they need to.
I really like the last pattern as it's easily scalable if you find you need more presenters or controllers with access to these kinds of models. It also lets you inject a repository, which means you can more easily move to a nice RESTful service-oriented architecture later.
If you haven't done much dependency injection before then please consider doing it through the constructor. This will help you avoid situations where things are trying to use your ViewModels before they're ready, and lets the ViewModels do their own work. You might also want to look at frameworks like Unity or Castle Windsor which can help you do this kind of wiring, but that's really only for big Enterprise projects (and not even all of them).
That's perfectly fine. Models are meant to be just what they sound like: data models. They're meant to be dummy objects that hold data, which the rest of the application can use as needed.
ViewModels are models that reflect the View. For example, suppose you had a LoginViewModel and an ManageUsersViewModel. Both ViewModels would work with the UserModel data object, however they are entirely different ViewModels for entirely different things.
In most cases, I would leave the responsibility of loading Models up to the ViewModel. For example, you normally wouldn't pre-load the Users list prior to the User logging in so you'd have their User object available. Insetad, your LoginViewModel would make it's own database call to get the User model of the user logging in, while the ManagerUsersViewModel would make its own database call to get the list of users that can be modified.
You must be thinking in a wrong way.. in MVVM your model are contained in ViewModels all the way to the views.. lets say if there is a ObservableCollection then there will be a property in you viewmodel for this and you should be initializing this collection in constructor/some method of the ViewModel.. both viewmodels will initialize ProductTypes like this.. In my opinion you should try create Classed For Model,ViewModel,Repository and use IoC in it..
here is a really good video on mvvm you should try this video and have a look at the code as well.
http://blog.lab49.com/archives/2650
If the List you mentioned is something that will never change you should try creating a singleton ViewModel for this and reference that viewmodel in other viewmodels.
Regards.
I am using ViewModels with asp.net MVC3. One of the thing I am curious about is, suppose I have an entity named Customers and it has Add, Edit, Delete screens. Assume that they all have different properties requirements.
For eg. Add may have address field but the edit screen may not have edit screen, delete may only use customer name more than anything else.
My question is, how do you create ViewModels for this? Do you go with the approach of shared ViewModels between add, edit and delete i.e a single viewmodel class that handles all for you or do you prefer to create viewmodels classes / page?
Advantage with shared viewmodel is it reduces development time and we can reuse classes. But big problem with this is that if you are using tool like Automapper you may expected results for different screens.
Disadvantage with one viewmodel/page is that it increases development time. Which way should I go?
My approach to view models is to use shared view models until the requirements (the data transported) to the view is different. That means I'm using a shared view model for example for CreateAddress and EditAddress in case all data transported to the view is the same. In case an additional field needs to be displayed in the view for example in the CreateAddress view I'm refactoring my view models and using different view models for CreateAddress and EditAddress.
For example for DeleteAddress I'd use a distinct view model from start because I know that the data displayed in the DeleteAddress view is almost never the same as in Create/EditAddress.
Another approach is to use dynamic view models, since view models should/must not implement business logic and act as DTOs between controller and view this approach has some benefits (No need to create logic free, throw away DTOs).
It depends upon situation. if you have similar requirements for different screens (validation, properties to render etc.) you can use the viewmodel across different views. If there is difference of one or two properties, i would still use the same viewmodel and where these properties are not needed i will put them in hidden inputs so they travel back with the form post not allowing unwanted results. Hidden fields, as all know, can be tweaked and its upon developer to decide if it is safe to use hidden fields. However, if i have different validation requirements for two screens then i definitely have to go with viewmodel/page approach. You can mix both approaches according to requirements as they say "there is no best way of doing things"
All fields that exists in a model can be changed. It doesn't matter if they are hidden or not. All the user has to do is to inspect your pages and try to figure out what fields exist in the model.
Then he can add those fields (for instance with Chrome Dev Tools) to make changes to them.
The safest way to get rid of that problem is to just have models that only have the fields that are allowed to be changed.
That said, go ahead and use the same model if all fields in the model should be allowed to be changed by all users. (And simply do not show the fields that should not be modified)
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.