How to update model and view model in MVVM pattern? - c#

I am struggling to implement MVVM pattern in my current project.
"ClassA" continuously gets required data from a remote device and stores this data inside it's fields. It is a model, I guess. ClassA updates required information via Update method.
"ClassB" continuously gets the data from "ClassA" and stores it in corresponding properties. Looks like it is a view model.
View is a simple MainWindow.xaml with a DataGrid inside.
I have the following questions:
1) How do I update ViewModel?
Should ClassB have an Update method, which accepts an instance of ClassA and updates corresponding fields?
2) Where do I store an instance of ClassA?
Should ClassA be a field of ClassB? If it should, then how do I update Model?
I thought of something like the following:
public void UpdateB()
{
ClassA.UpdateA();
this.FieldOne = ClassA.FieldOne;
this.FieldTwo = ClassA.FieldTwo;
}
4) Does model have it's update method at all or model just stores the data?
3) What do I do inside MainWindow.cs, aside from windows initialization? Do I update view model (ClassB) there?

I find it best to have a object representing an item in each layer of abstraction. This includes the form of the data as it exists on the disk. Remember that in MVVM, the only real goal is to promote loose coupling between the interface(User Interface) and the implementation(ViewModel functionality).
For example, if I have objects stored in XML files, I will have an object in my data access layer that exists only for the proper management of the XML data. Let's call it ObjectXml. This object only contains data in the form that is native to the data on the disk. In this case, all data has a string representation, as in the XML files.
In the model layer, you will have the data representation of the XML file in the expected data types. Let's call this Object. The property getters and setters may access and set the string representation of the data by performing conversions in both directions. This way, the data is ready to be persisted to the data source(xml file, database etc.).
In ObjectViewModel, properties may access those in Object. The viewmodel contains all the members for representing and modifying the model.
Note that ObjectXml is really only beneficial when you are only allowed to store string information, or when a suitable schema does not exist for your data types.
At the end, you have a hierarchy of containment such as the one below:
public class ObjectXml
{
[XmlArray("People"), XmlArrayItem("Person")]
public List<PersonXml> People { get; set; }
//PersonXml is an xml data model similar to this one
[XmlElement("Item")]
public string Items { get; set; }
}
Here is the model for the Xml object:
public class Object
{
private ObjectXml _xmlContext;
public Object(ObjectXml xmlContext)
{
this._xmlContext = xmlContext;
}
public List<Person> People
{
get
{
//Person requires a constructor that takes a PersonXml object in order for this to work properly
return this._xmlContext.People.Select(x => new Person(x)).ToList();
}
set
{
this._xmlContext.People = value.Select(x => new PersonXml(x)).ToList();
}
}
public double Item
{
get { return double.Parse(this._xmlContext.Item); }
set { this._xmlContext.Item = value.ToString(); }
}
}
Obviously, it's not wise to name your class Object as it's a reserved word in C#. Hopefully I've given you some ideas of how to access and update data in a robust and extensible manner.
In short, you don't need an update method at all. Also, short of constants and property backing fields, there are very few reasons to need direct field access in C# MVVM.
See below. Do not listen to people that say the ViewModel and Model need to be decoupled. The main purpose of the model is an intermediary layer that prepares data to be saved or loaded into the program and to store data in a way that is agnostic to both the data and the program functionality(ViewModel)
You do not need an update method. Use properties that access the data model and persist to the data storage(xml, database etc.) if needed.
You do not need an update method.
You should not have to do anything inside of ViewModel.cs. Only code that modifies the view should be in the codebehind. The only ViewModel you should ever access in a view is one that follows the form of MainWindowViewModel, which is more like an ApplicationViewModel that carries instances of other required viewmodels.
Finally, don't get stuck using an overcomplicated MVVM "framework" as most of the functionality is not useful or necessary.

Like stated in Yuris comment, you should not use any update method, but rather implement the INotifyPropertyChanged interface. Like the name says this notifies all subscribers when the value of a certain Property changed.
This is a nice article which contains code to a minimalistic MVVM implementation. If you have trouble implementing the pattern from scratch, try to start with this example and replace the existing classes with your own one-by-one.
As to the update mechanic inside your MainWindow.cs - you don't need any, if you specify the DataBinding in your xaml code like it is done in the example linked above.
I hope this helps you getting started!

Related

WPF (MVVM): where to put existing "assembly" / "application logic" - in a model or viewmodel [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I have some kind of experience with WinForms coding but I am trying to do my new stuff with WPF (and the mvvm pattern).
One thing I am going round in circles for days searching the internet is to get the following right:
What do I have to implement in a model and what in the viewmodel when it goes down to "manage the repository (model?) data".
(I think) I do understand the basic concept of mvvm and decopeling all the data but I struggle to figure out the right implementation.
Let's assume I have an existing service (application without any UI) which is able to read values from a (ini) configuration file, do some stuff what its intended for, and write configurations to the local registry. Perhaps in future I want change the configuration to be stored in xml or json instead of ini. From my point of view this is all well placed in the existing code - let's say a configuration.cs file with a class configurations - which currently has absolutely nothing to do with my new wpf console application I want to implement next.
namespace ExistingConfigurationCode
{
public enum Setting
{
some,
values
}
public class ConfigurationItemProperties
{
public property1
public property 2
}
public class ApplicationConfiguration
{
List<ConfigurationItemProperties> config;
public void LoadConfig()
public void SaveConfig()
}
}
As just said, now I do want to implement a UI to enable a user to set up those configurations.
For what I have understand until now is:
the view is only the view and contains no logic at all
the viewmodel is responsible to "deliver" all needed informations to the view and receive commands from the view
the model is a model of the data we are dealing with
My problem in understanding (and knowledge how to proceed) is:
is this existing class already my model? But it does not make sense to add all the RaisePropertyChange stuff in this class because it is also used in the service. Also I have seen a lot of tutorials where I am told to not put any code in the model
if the existing class should be in my view model, what do I need the model for than?
Should the model have only a reference to my already existing class and control all read and write stuff to the registry/xml/ini through some kind of a wrapper?
Where do I have to add the "RaisePropertyChange" getter and setter? Because they are "controlling" the UI I would guess they should be placed in the view model, but I have seen a lot of examples where they are also in the model?
I got some kind of stuck here.
I thought the binding should be between the view and the view model, so the RaisePropertyChange should be in the view model, but in this case I would have to recreate everything a second time in the view model
Additional informations in response to comments
I understood now, that I can use my existing code as the model.
Besides the already existing "execution engine" which is utilizing the existing namespace/class, I have to create two applications with UI. An "admin console" and an end user console.
(I think) I am fine with the admin console, because it has a view for all the properties of ConfigurationItemProperties, so I can following Fabios first explanations.
But the second UI for the end user should have a stripped down UI, probably a listview with some checkboxes per list view item. And here is my problem.
For the listview I need the ObservableCollection, but for the items in the list view I need the "facade" fabio mentioned. Am I right so far?
If so, the ObservableCollection AND "ConfigurationItemPropertiesFacade" are working with the "model" which does not have any implementation of INotifyPropertyChanged or INotifyCollectionChanges stuff. But I think the "collections" must refer to the "single items" from the facade because the collection (from the view model) has no reference to the facade in the view model.
Try to think about MVVM like about three layers(not files) of your application.
View - namespace/project which contains only view logic(XAML and code
behind)
Model - namespace/project which contains all "business logic"
ViewModel - namespace/project which contains logic to link View and
Model without knowing about View's namespace. Another words ViewModel layer's responsibility to be a bridge between Model and View - Call Model's method, raise PropertyChanged event for when some value changed to inform View about changes.
So keep all your logic of configuration in the Model namespace.
In case when Model class need to be represent in the View with editing possibilities, create Facade class in the ViewModel layer
public class ConfigurationItemPropertiesFacade : INotifyPropertyChanged
{
private ConfigurationItemProperties _Model;
public string Property1
{
get { return _Model.Property1; }
set
{
if(Equals(_Model.Property1, value)) return;
_Model.Property1 = value;
RaisePropertyChanged();
}
}
public ConfigurationItemPropertiesFacade(ConfigurationItemProperties model)
{
_Model = model;
}
}
Use ConfigurationItemPropertiesFacade class as ViewModel in the View.
With this approach your Model layer stays clean and can be used anywhere.
In response on comment:
So tutorials telling it is not allowed to put "code" in the model are wrong, right?
Again try thinking about Model in MVVM not like a one class/file, but layer/namespace/project which can contains more then one class.
There is no right or wrong - you can implement your logic as you fill better suite your specifications. But if you will respect Single responsibility principle (https://softwareengineering.stackexchange.com/a/17170/102569), then you will separate responsibilities of ApplicationConfiguration to (I didn't know inner logic of methods Load and Save)
"Model" class which represents only data, class which has no
functionality just properties for keeping data.
You have this already ConfigurationItemProperties
"Service" classes which contains functionality of saving and loading
configurations. Your class can be spitted in two classes.
// Have one responsibility take configurations as parameter and save them somewhere
public class SaveService
{
public void Save(List<ConfigurationItemProperties> items) {}
}
// Have one responsibility load configurations and return them to the caller
public class LoadService
{
public List<ConfigurationItemProperties> Load() {}
}
So then your ViewModel will use those classes to represent and modify configurations in UI.
public class ViewModel
{
private readonly LoadService _LoadService;
private readonly SaveService _SaveService;
//Here you can use your"Facade" implementation
private ObservableCollection<ConfigurationItemPropertiesFacade> _Items
public ObservableCollection<ConfigurationItemPropertiesFacade> Items
{
get { return _Items; }
set
{
_Items = value;
RaisePropertyChanged(nameOf(Items));
}
}
public ICommand Save { get; set; }
public ICommand Load { get; set; }
public ViewModel(LoadService loadService, SaveService saveService)
{
_LoadService = loadService;
_SaveService = saveService;
// Create command instance for Save
// Create command instance for Load
var itemsList = _LoadService.Load();
var facadeItems = itemsList.Select(item => new ConfigurationItemPropertiesFacade(item));
Items = new ObservableCollection(facadeItems);
}
}
Let's think about these definitions:
Model - Data access and business Logic.
ViewModel - it's responsibility is to provide model's data and logic to view in such way that is easily consumable from view.
I believe that these definition gives you clear answer:
ExistingConfigurationCode class should be considered as part of your model.
Few more thoughts however:
INotifyPropertyChanged and INotifyCollection changed is not limited to DataBinding or WPF. These interfaces are much more general.
There nothing wrong about implementing INotifyPropertyChanged in a Model if you want your model to notify other layers or compoments about changes
It's common practice that you bind your Views directly to Model entities. ViewModel often just expose entity from Model as a property.
Wrapping model properties in ViewModel is one way of doing it. Another way is having separate properties in ViewModel with their own backing fields. You set the ViewModel properties to initial values when user visits the page and you save the edited values back to Model when user clicks save.

Where Do You Store Data in a GUI Application?

I've always heard that you should separate GUI/Data/Logic components, like the MVC pattern.
So, I am wondering: In a GUI application, where do you actually store the data?
Here is an example (using C# terminology):
Suppose you have a GUI that takes user input, does some analysis, and displays results in a table. The user can have several analyses in one window, so there is a ListView at the bottom that allows the user to select which analysis is currently displayed (the selected item gets displayed).
In order to display this, the analysis data must be stored somewhere. I have always done one of two things:
Put all the data into a single object and store it in the ListViewItem's "Tag" property
Extend "ListViewItem" and just add whatever properties I need.
But, this means I am storing the data inside of the ListViewItem.
Is there a more appropriate place to keep track of the data?
I could add it as private members to the main form, but that seems like the same thing.
The only other thing I can think of is to make some global class that I can reference whenver I need to.
Thanks.
As I understand, you have some ListViewItems. Each ListViewItem is associated with your business logic object and after select one of ListViewItem you want make some operations over this buisness object. In similar situations I usually make Data Object like
struct MyDataObject
{
string Id;//very often data object need to have Identifcator, but not always
//some fields
}
and add to data object constructors for typical user input.
After that I make business logic layer contains available algorithms for this data objects. For simple projects, this is a static class like
static class MyDataObjectOperationService{
void MakeSomething(MyDataObject myDataObject);
object GetSomething(MyDataObject myDataObject);
...
}
For big projects that is usually interface. Also I usually make a data layer interface for getting this data object. For example
interface IMyDataObjectRepository{
IList<MyDataObject> GetAll();
MyDataObject GetById(string id);
//CRUD operations if it need
}
After that I put into ListViewItems ids of Data Objects and on ListViewItemClick getting selecting id, after that getting DataObject by Id using data layer classes and make some operations using business logic layer classes. If I need to save DataObject changes or create new DataObject I using data layer classes.

MVVM: Binding to Model while keeping Model in sync with a server version

I've spent quite some time to try and find an elegant solution for the following challenge. I've been unable to find a solution that's more than a hack around the problem.
I've got a simple setup of a View, ViewModel and a Model. I will keep it very simple for the sake of explanation.
The Model has a single property called Title of type String.
The Model is the DataContext for the View.
The View has a TextBlock thats databound to Title on the Model.
The ViewModel has a method called Save() that will save the Model to a Server
The Server can push changes made to the Model
So far so good. Now there are two adjustments I need to make in order to keep the Model in sync with a Server. The type of server is not important. Just know that I need to call Save() in order to push the Model to the Server.
Adjustment 1:
The Model.Title property will need to call RaisePropertyChanged() in order to translate changes made to the Model by the Server to the View. This works nicely since the Model is the DataContext for the View
Not too bad.
Adjustment 2:
Next step is to call Save() to save changes made from the View to the Model on the Server. This is where I get stuck. I can handle the Model.PropertyChanged event on the ViewModel that calls Save() when the Model gets changed but this makes it echo changes made by the Server.
I'm looking for an elegant and logical solution and am willing to change my architecture if it makes sense.
In the past I 've written an application that supports "live" editing of data objects from multiple locations: many instances of the app can edit the same object at the same time, and when someone pushes changes to the server everyone else gets notified and (in the simplest scenario) sees those changes immediately. Here's a summary of how it was designed.
Setup
Views always bind to ViewModels. I know it's a lot of boilerplate, but binding directly to Models is not acceptable in any but the simplest scenarios; it's also not in the spirit of MVVM.
ViewModels have sole responsibility for pushing changes. This obviously includes pushing changes to the server, but it could also include pushing changes to other components of the application.
To do this, ViewModels might want to clone the Models they wrap so that they can provide transaction semantics to the rest of the app as they provide to the server (i.e. you can choose when to push changes to the rest of the app, which you cannot do if everyone directly binds to the same Model instance). Isolating changes like this requires still more work, but it also opens up powerful possibilities (e.g. undoing changes is trivial: just don't push them).
ViewModels have a dependency on some kind of Data Service. The Data Service is an application component that sits between the data store and the consumers and handles all communication between them. Whenever a ViewModel clones its Model it also subscribes to appropriate "data store changed" events that the Data Service exposes.
This allows ViewModels to be notified of changes to "their" model that other ViewModels have pushed to the data store and react appropriately. With proper abstraction, the data store can also be anything at all (e.g. a WCF service in that specific application).
Workflow
A ViewModel is created and assigned ownership of a Model. It immediately clones the Model and exposes this clone to the View. Having a dependency on the Data Service, it tells the DS that it wants to subscribe to notifications for updates this specific Model. The ViewModel does not know what it is that identifies its Model (the "primary key"), but it doesn't need to because that's a responsibility of the DS.
When the user finishes editing they interact with the View which invokes a Command on the VM. The VM then calls into the DS, pushing the changes made to its cloned Model.
The DS persists the changes and additionally raises an event that notifies all other interested VMs that changes to Model X have been made; the new version of the Model is supplied as part of the event arguments.
Other VMs that have been assigned ownership of the same Model now know that external changes have arrived. They can now decide how to update the View having all pieces of the puzzle at hand (the "previous" version of the Model, which was cloned; the "dirty" version, which is the clone; and the "current" version, which was pushed as part of the event arguments).
Notes
The Model's INotifyPropertyChanged is used only by the View; if the ViewModel wants to know whether the Model is "dirty", it can always compare the clone to the original version (if it has been kept around, which I recommend if possible).
The ViewModel pushes changes to the Server atomically, which is good because it ensures that the data store is always in a consistent state. This is a design choice, and if you want to do things differently another design would be more appropriate.
The Server can opt to not raise the "Model changed" event for the ViewModel that was responsible for this change if the ViewModel passes this as a parameter to the "push changes" call. Even if it does not, the ViewModel can choose to do nothing if it sees that the "current" version of the Model is identical to its own clone.
With enough abstraction, changes can be pushed to other processes running on other machines as easily as they can be pushed to other Views in your shell.
Hope this helps; I can offer more clarification if required.
I would suggest adding Controllers to the MVVM mix (MVCVM?) to simplify the update pattern.
The controller listens for changes at a higher level and propagates changes between the Model and ViewModel.
The basic rules to keep things clean are:
ViewModels are just dumb containers that hold a certain shape of data. They do not know where the data comes from or where it is displayed.
Views display a certain shape of data (via bindings to a view model).
They do not know where the data comes from, only how to display it.
Models supply real data. They do not know where it is consumed.
Controllers implement logic. Things like supplying the code for ICommands in VMs, listening for changes to data etc. They populate VMs from Models. It makes sense to have them listen for VM changes and update the Model.
As mentioned in another answer your DataContext should be the VM (or property of it), not the model. Pointing at a DataModel makes it hard to separate concerns (e.g. for Test Driven Development).
Most other solutions put logic in ViewModels which is "not right", but I see the benefits of controllers overlooked all the time. Darn that MVVM acronym! :)
binding model to view directly only works if the model implement INotifyPropertyChanged interface. (eg. your Model generated by Entity Framework)
Model implement INotifyPropertyChanged
you can do this.
public interface IModel : INotifyPropertyChanged //just sample model
{
public string Title { get; set; }
}
public class ViewModel : NotificationObject //prism's ViewModel
{
private IModel model;
//construct
public ViewModel(IModel model)
{
this.model = model;
this.model.PropertyChanged += new PropertyChangedEventHandler(model_PropertyChanged);
}
private void model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Title")
{
//Do something if model has changed by external service.
RaisePropertyChanged(e.PropertyName);
}
}
//....more properties
}
ViewModel as DTO
if Model implements INotifyPropertyChanged(it depends) you may use it as DataContext in most cases. but in DDD most MVVM model will be considered as EntityObject not a real Domain's Model.
more efficient way is to use ViewModel as DTO
//Option 1.ViewModel act as DTO / expose some Model's property and responsible for UI logic.
public string Title
{
get
{
// some getter logic
return string.Format("{0}", this.model.Title);
}
set
{
// if(Validate(value)) add some setter logic
this.model.Title = value;
RaisePropertyChanged(() => Title);
}
}
//Option 2.expose the Model (have self validation and implement INotifyPropertyChanged).
public IModel Model
{
get { return this.model; }
set
{
this.model = value;
RaisePropertyChanged(() => Model);
}
}
both of ViewModel's properties above can be used for Binding while not breaking MVVM pattern (pattern != rule) it really depends.
One more thing..
ViewModel has dependency on Model. if Model can be changed by external service/environment. it's "global state" that make things complicate.
If your only problem is that changes from the server get immediately re-saved, why not do something like the following:
//WARNING: typed in SO window
public class ViewModel
{
private string _title;
public string Title
{
get { return _title; }
set
{
if (value != _title)
{
_title = value;
this.OnPropertyChanged("Title");
this.BeginSaveToServer();
}
}
}
public void UpdateTitleFromServer(string newTitle)
{
_title = newTitle;
this.OnPropertyChanged("Title"); //alert the view of the change
}
}
This code manually alerts the view of the property change from the server without going through the property setter and therefore without invoking the "save to server" code.
The reason you have this problem is because your model doesn't know whether it is dirty or not.
string Title {
set {
this._title = value;
this._isDirty = true; // ??!!
}
}}
The solution is to copy the server changes via a separate method:
public void CopyFromServer(Model serverCopy)
{
this._title = serverCopy.Title;
}

Knockout js and Raven DB

I'm currently developing an application based on no-sql (using raven db). The core aspect of this application is a tree-like data structure with many nodes, subnodes and so on.
Currently, each node or subnode is represented by a c# object. A parent-child relationship is made with a collection of subnodes on the parent node, a forward-only relationship.
The whole thing is handled by ad hoc forms, in an Mvc application, with proper GETs and POSTs for each data type. The whole graph is stored as JSON on Raven DB.
Now the goal is to modify the UI part using knockoutjs. Since KO works with json data structures as well, I was wondering if there is a way to make the ravendb json structure "knockout compatible", meaning I can directly use it without having to make a KO specific structure (to implement observables, etc) and then create a mapping between the two.
A sample of the object graph:
public class NodeA
{
public string Name {get;set;}
public List<SubNode> Childs {get;set;}
}
public class SubNode
{
public string Name {get;set;}
public bool SomeBool {get;set;}
}
public class NodeB
{
public string Name {get;set;}
public int SomeInt {get;set;}
}
public class GraphToStore
{
public List<NodeA> NodeAList {get;set;}
public List<NodeB> NodeBList {get;set;}
}
The read/write part would still be handled server side, with ajax calls after stuff gets updated on the UI. Validation would be server-side and returned to the client via ajax calls too. My problem is as I said making the ravendb json work with knockoutjs, otherwise I have to reconstruct the whole thing and map it, and the graph is huge (50+ classes).
Take a look at Knockout-mapping-plugin. It will "automagically" generate the knockout compatible viewmodel with one call.
You would do something like
var viewModel.myRavenDbData = ko.mapping.fromJSON(json data variable);
var unwrappedData = viewModel.myRavenDbData(); // need only if viewModel.myRavenDbData is an observable
After you have this working, breakpoint after the call to mapping and explore the data structure. Generally, it will look like your data structure with ko.observables for the actual values. All the nodes needed for navigation will be normal javascript objects.
Yes you can use the Knockouts Mapping capabilities and create ViewModels directly from the model objects. But, I have two points:
1) I think that the fact that the objects are stored in RavenDB does not metter. Your MVC applications retrieves the objects from RavenDB - so they are deserialized from JSON and than they are served to your JS page via REST interface, so they are serialized again into JSON. So you are not working directly with the RavenDB's JSON structure, it is a standard CLR object serialized to JSON.
If you want to work directly with Raven, you have to plug your application directly to raven's interface - and that is not a good idea (but of course in the metter of performance it should work great).
2) I don't think that it is good idea to use your model objects as ViewModels, only by using the knockout mapping plugin.
Soon you will need to add some logic to the view model. Either for computing values to be showed in the view, or adding some action logic (save/edit...etc).
For the first case, you can define your viewmodels on the server side and use the mapping plugin.
For the later, you will have to write the view models in javascript anyway. I would recomend start writing the viewmodels in javascript directly.
It works the best for me.

Add editing to MVVM in a hierarchical data structure

This question is a follow-up of this older one, and it's more of a confirmation than an open question.
My ViewModel instance has a private instance of the Model, _modelInst.
The ViewModel has exclusive access to the Model's data during editing (so the Model doesn't need to implement INotifyPropertyChanged).
Now there are three ways I came up with how to edit the Model data from the View:
Getting/setting directly on the Model instance
e.g. for simple value fields
return _modelInst.fieldname;
_modelInst.fieldname = value;
This one's easy to implement...
Creating a ViewModel instance and operating on the parent's data structure
e.g. for more complex object types like structs:
Creating a new ViewModel for that type.
The ViewModel knows the parent and its fieldname.
displaying that in a ContentControl+DataTemplate
getting / setting:
via methods of the parent with the fieldname as parameter,
overwriting the whole original object even if only one field is changed
This means creating a new interface (with update routines working on _modelInst), implemented by the parent, for each of these structures.
Creating ViewModel instances with no direct knowledge of the parent's data structure
e.g. for (lists of) classes within parent classes
Creating a new ViewModel for each class
Sending update instructions to the parent via
commands
messages
reflection (parent knows which child called the function
by comparing the instance to all stored children)
All of these are a big mess implementing, creating functions for
every field of the model that is editable.
Which means pretty much all fields of the model...
(4.) One could create a generic ViewModel which works via reflection alone, where each
subobject knows its parent and its fieldname (+index, if in a list).
Only the root's logic would then interfere with the model.
But that solution would also require a means to store the path to a field within _modelInst.
Is there any other (more simple) way to achieve this?
Did I misunderstand the principles of MVVM (again)?
Is MVVM suited for manipulation of large hierarchical data structures?
Hopefully these resources will help; they helped me quite a bit as I learned MVVM and how to approach representing object graphs/hierarchies with view models:
Editable Object Adapter
Editable Collection Adapter
MicroModels
This is an excellent question for which I do not feel there is a good answer that comes stock with the MVC pattern.
ViewModels work great when the model they map to has no children.
But when the model has children, as in
Customer
-->Order
-->Country
(imagining Country were a child object of Customer) the design pattern kind of breaks down.
The best thing I've found is to use inheritance and selectively expose
only those children for which you need viewmodel logic. Otherwise, just access
the model's properties of the view that will come in via inheritance.
public class CustomerView : Customer //inherits from Customer (model)
{
public CustomerView(Customer customer)
{
this.FirstName = customer.FirstName
//etc..
//Only if you need it, that is if you have some display-specific
//logic relating to country for a given view, you create
//a CountryView class that inherits from Country and gets populated
//by an instance of it as well
this.CountryView = new CountryView(customer.Country)
}
public CountryView CountryView {get;set;} //sadly you cannot override Country but you may be able to shadow it.
public string DisplayColor
{
if(base.FirstName == "Joe")
{
return "red";
}
return "";
}
}
This gets messy when dealing with grandchildren. If anyone has a better solution, I would love to hear it.
Thanks

Categories