WPF, MVVM, Business Object with Validation don't match very good - wpf

For my WPF-Application I decided for MVVM. Here is my Concept how I will implement this pattern.
My Models (Business Objects) are responsible for the validation (that's a must for me).
ViewModels are responsible to wrap my Model for a friendly User-Interaction and some security aspects.
My first question was about wrap or not wrap my Model in ViewModel.
When I don't wrap my Model in ViewModel and expose the Model directly to the view – then I don't understand why I need a ViewModel (it seems sensless)
ViewModel should wrap the Model for various reasons:
I don't like direct binding to the strongly typed properties in Model (DateTime, int, …), because when I do this => WPF takes control over my validation for this types. That's really bad, because when the user write ‘aaaa’ in a Datepicker, my Model is valid (my model never know about that, because WPF takes the control over strongly typed properties) and the Save-Button is enable – that's really wrong.
I don't expose all properties of my Model to the view, my ViewModel should protect my Model (I have some properties, that should have at presentation layer only getter and no setter)
My Decision is that ViewModel should definitely wrap the Model. So the ViewModel implements INotifyPropertyChanged.
But now I have problem with the business validation.
When I take the nice IDataErrorInfo, then I have the whole business rules in the ViewModel, that's breaks my concept. The business rules should definitely be in the model.
Example: When user choose Type A, then Field 1, and Field 2 are mandatory. When user choose Type B, then Field 3 is mandatory – this field should be marked as red and the Save-Button is disable when is it not valid. Also more heavy things like free/occupied DateTime-Ranges.
It's definitely bad, when I do this things in ViewModel, because most things are business part.
So how I can achieve this?
At the Moment I have this workaround:
All ValidationRules are in the Model as simple Methods, e.g.
public string ValidateBirthday(string birthay)
{
if (...)
{
return "Birthday should be…";
}
return string.Empty;
}
In my ViewModel I implemented the IDataErrorInfo, and redirect to my Model-Validation like this:
public string this[string columnName]
{
get
{
switch (columnName)
{
case "Birthday":
return Model.ValidateBirthday(Birthday);
case "XXX":
return Model.ValidateXXX(XXX);
case "YYY":
return Model.ValidateYYY(YYY);
break;
}
}
}
I never see something like this (the redirect to Model) in an example, so I'm very doubtful about my implementation.
Is my workaround OK or do you see any problems about this?
I try to give more information about what I mean…
I know about the implementation INotifyPropertyChanged and IDataErrorInfo in the Model.
This works good with direct Binding from View to Model.
Direct Binding from View to Model:
public class PersonViewModel : INotifyPropertyChanged
{
private Person _personModel;
public Person PersonModel
{
get { return _personModel; }
set
{
if (_personModel != value)
{
_personModel = value;
NotifyPropertyChanged();
}
}
}
public PersonViewModel(Person person)
{
PersonModel = person;
}
…
}
View:
<DatePicker Text="{Binding PersonModel.Birthday}"/>
The big disadvantage is: WPF takes the Control over all strong typed Property.
Example:
The user typed 07/20/2008 in the datepicker, so the PersonModel will be informed and PersonModel can check this, when OK, then PersonModel is valid => SaveButton is enable.
Now the user typed 'aaa' in the datepicker, WPF takes the control over this validation, because it's a binding to a strongly typed property (DateTime). PersonModel will not be informed about that, so the PersonModel is still valid => SaveButton is enable!
So for that 'problem' I need the ViewModel correctly.
ViewModel wrap the Model like this:
public class PersonViewModel : INotifyPropertyChanged
{
private Person _personModel;
public string Birthday
{
get
{
if (_personModel. Birthday!= null)
{
return ((DateTime) _personModel. Birthday).ToShortDateString();
}
else
{
return String.Empty;
}
}
set
{
if (_personModel. Birthday.ToString() != value)
{
DateTime dateValue;
if (DateTime.TryParse(value, out dateValue))
{
_personModel.Birthday = dateValue;
…
}
else
{
…
}
}
}
}
public PersonViewModel(Person person)
{
_personModel = person;
}
…
}
Now I don't bind the Model direct from View. I bind the Properties from ViewModel that wrapped the Model.
<DatePicker Text="{Binding Birthday}"/>
The big advantage is: now I have the full control about what the user types in the fields.
When the user types strings like 'aaa' in Datepicker I can catch this => set the state to invalid and SaveButton is disabled.
That's one reason, why I don't take the direct binding from View to Model.
Other reason are readonly Property. In Model I have get and set on every Property, but for security Issue I won't offer all Properties from Model with get and set. So this can also solved by ViewModel by wrapping this Properties with only get. With direct Binding you can't do all this things.
My point is, I will definitely wrap all Properties from my Model in ViewModel, but how can I use the nice IDataErrorInfo in Model (It works only with direct Binding)?

You are mixing two concepts here: Bussiness objects and validation.
Almost every system nowadays uses the client-server architecture, even if its an standalone application.
In such scenario you have two validation locations:
The client is responsible for ensuring that the data entered is valid before sending anything to the server in order to enhance user experience and avoid server overloads and security issues.
The server is responsible for the verification of the incoming data, to avoid malformed, misformatted data and security issues.
Also:
The Bussiness Objects (BO) are the classes used by server, tipically represeting the data base.
The Data Transfer Objects (DTO) are the classes that the server sends to the client.
The ViewModels are both the backend code for the UI and the wrappers for the DTOs.
Your model objects shouldn't have any logic, since you will spoil them with some code that at some point you will need to reuse.
As exposed here, you should separate that validation logic into services that only know about that object and how to validate them. This way, you can use validation services from the UI.
Your Save button should react only on UI changes, and you will only get those from a ViewModel.
Basically, you will be applying SOLID principles here: Each layer has very clear responsibilities (model -> data, services -> validation, dto -> data ready for the client, viewmodels -> UI interaction). All the code will be easy to work with, easy to extend and easy to refactor.
Edit
1st and 2nd questions:
UI only validates the input: no random characters in number fields, no sql characters in text fields, Date has correct format, etc.
Thinks like "if this then that" should be handled by the backend, as you describe:
Save is clicked.
UI data is valid.
DTO sent to backend.
Backend analizes DTO and it is not valid.
Backend sends back the errors found.
UI shows the errors found.
3rd question:
That looks right to me.
4th question:
DTO is just a concept, you can use a real backend server that communicates via WCF, or you can just have a bunch of classes that act as a service but are called in the same application domain (like any other project reference). In either case you can choose what data is being sent and received.
You should start developing in that direction and then see what better fits you.

Related

Do I have too many WPF layers here?

I think I'm on my way to finally grokking MVVM. I was just looking at a situation I found myself in and I'm wondering if I should combine two of my layers. I currently have a structure like this:
Domain models (in a separate .net project)
WPF-side "models" which wrap domain models and track dirty state
WPF ViewModels
Views
The question is whether I should combine 2 and 3. Right now #2 is the layer that gets passed around by my mediator to facilitate all the viewmodels knowing what document is currently opened. But I think my code for 2 and 3 is too similar and is unnecessary duplication at this point.
Example:
// in layer 2, class ProjectDocument
// Project is an instance of the domain model
public string Name
{
get { return Project.Name; }
set
{
if (Project.Name == value) return;
Project.Name = value;
Dirty = true;
}
}
// in layer 3, class ProjectSettingsViewModel
// _project is a ProjectDocument
public string Name
{
get { return _project.Name; }
set
{
_project.Name = value;
OnPropertyChanged("Name");
}
}
Seeing that struck me as unnecessary. So should I combine them? On one hand, it would remove a lot of redundant code and I'd have fewer places to update when I change things. On the other, I might be giving one class too much responsibility, and also it seems inappropriate for an actual ViewModel to be passed around to other VMs via my mediator. The ProjectSettingsViewModel wouldn't use even half of the fields on ProjectDocument if they were combined.
Maybe I'm looking at this the wrong way. Is there a better way to reduce the duplication while still keeping the responsibilities separate?
I have a master viewmodel that handles application states like which document/tab/window is open and I have an ISettingssService for other global needs. Passing one viewmodel to another is discouraged and you might want to think about creating am iSettings service that can be injected into the viewmodels, then the viewmodels can interact with "global" settings but the viewmodels are still decoupled because they do not depend on another viewmodel.
So, I would not combine them. Either I would have a dictionary of documents that can be open in the master viewmodel with a current open doc property or move this logic to a service/interface that gets used by each viewmodel.
Hope this helps.

Data sharing between multiple ViewModels

Further to my question how can I bind Bing Pushpins from multiple models?
This is pretty new to me and I have been searching through the web but there seem so many different approaches to MVVM and then adding in WP7 and I have got a bit confused
I am now trying to work out the best way to share data between ViewModels or even if that is the best way to do it.
What I mean is I have, for example
My models: PeopleModel, BuildingModel
My ViewModels: PeopleViewModel, BuildingViewModel (which contain Observable collections of the model)
At the moment a Timer is used to update the lists from a Webservice. The ViewModel because it is static is able to be updated during the lifetime of the application. I am not sure this is the most sensible approach though but I need some form of background sync to fit the requirements.
The People and Building contain a location but not anything regarding what image it should display as a pushpin. So I was thinking if I had a my map view containing a MapViewModel that is linked somehow to the ViewModels but I am not sure how you would do this.
I looked at MVVMLight and it seems you can register the ViewModels at start so it would be possible to add links to the other ViewModels and not worry about the lifetimes of them?
However given that there is extra information within the Models that the Map isn't interested in I wonder if is better to have a self-contained MapViewModel that contains lists of Custom pushpins of some type (so PeoplePushpins, BuildingPushpins). If I go this route I would like to know how you update the MapViewModel from data updated in the other Models.
What I mean is the running timer in PersonViewModel detects a change in the list, so updates its own list. I the need to send notification to the Map that there is an update which then will update itself from that.
Any help/advice gratefully received.
With MVVMLight you can use messaging to send data between models:
//build class to send as message
public class AddPushPinMessage
{
public PushPin PushPin { get; set; }
}
public class ReceivingViewModel
{
public ReceivingViewModel()
{
Messenger.Default.Register<AddPushPinMessage>(this, (m) => AddPushPin(m));
}
void AddPushPin(AddPushPinMessage msg)
{
//handle message
}
}
public class SendingViewModel
{
private object SendPushPin(PushPin key)
{
Messenger.Default.Send<AddPushPinMessage>(new SetPushPinMessage() { PushPin = key });
return null;
}
}

Server-side Validation for Silverlight Application

I was just about to implement IDataErrorInfo, when I saw INotifyDataErrorInfo was to be used for asynchronous validation. When digging a bit further, I noticed the examples using those interfaces were all on the ViewModel. I need my validation on the model, and I need the errors stored with the model for persistence. I have a large graph with many entities. This graph needs to be passed back to the server for a complex validation. I'm not sure what approach I am supposed to use now.
Do I simply move my inteface implementations to the model?
Another example I saw had a separate validation service. In my case, my validation rules are complex, and I was thinking of using Windows Workflow and its rule engine to improve the maintainability of the validation rules.
Do I need a separate validation service?
Once the validation has completed, the graph must be passed back to the client. Any errors/warnings need to be displayed then.
Should I implement INotifyDataErrors in the model and raise the event when the validation returns to the client to post the errors to the View (through ViewModel)?
As it turns out, I am having trouble referencing the assembly that contains INotifyDataErrors in the class library. It creates a conflict in an assembly that is sharing those classes.
When you have big projects RIA may not be a good idea, for example applications with different layers (Services, Application, Domain, Infrastructure).
Some time ago I had to implement Validation in a Silverlight app with complex rules. I was using Self-tracking entities generated with the Entity Framework. And one of my need was to rehuse all the validation code.
First I tried to use the EntLib Validation Block and use the same code on both the client and the server. This approach doesn't work as you get some problems as SL and .NET4.0 use different versions of the DataAnnotations assembly.
Finally I ended up writing some sort of validation service on the server that returns the errors of an entity if any. Something like this:
interface IValidate
{
IEnumerable<string> Validate(Entity entity);
}
And then on the Client make the ViewModels implement INotifyDataErrorInfo (this interface supports async validation), so you can validate the entity with the Service and save the errors on the ViewModel.
class SomeViewModel : INotifyDataErrorInfo
{
public Entity Entity { get; set; }
public void Validate()
{
this.ClearErrors();
// this method make the service calls
var service = -- service instance --;
var errors = -- get errors from service --;
foreach (string error in errors)
this.AddTopLevelError(error);
}
{...}
}
This way all the validation logic lies on the Server and it can change at any time without affecting the client, because all the entities are passed througth this service before being added to a DataBase (if you're using one).
The service could also return the errors and the property associated with the error, this way you could get a richer interaction with Silverlight. So the service could be:
interface IValidate
{
IEnumerable<PropertyError> Validate(Entity entity);
}
class PropertyError
{
public string PropertyName { get; }
public IEnumerable<string> Errors { get; }
}
Here you can notice that the validation rules could change on the server, and it doesn't matter how this logic is implemented. All this works fine and meets your requeriments, the problem is that Silverlight requires that the object being validated contains all the properties with errors.
This is not a common scenario when working with Databases, as you could have for example (and this is a simple model)
this model was done using Entity Framework 4.1
Because if you have a user instance and want to access to the Email property, you'll have to type: user_instance.Person.Email. So the Email property isn't in the user type, and here is the problem with this solution because you may want to validate the EMails too.
Is this wasn't like this, when you have a ViewModel (implementing INotifyDataErrorInfo) with an Entity (like above) and wants the entity (User in this case) to be validated, you only have to add an error to the property Entity.Person.Email.
But the world isn't perfect, so the solution i found was to duplicate each one of the properties to be validated on the ViewModel, something like this:
class SomeViewModel : INotifyDataErrorInfo
{
public User Entity { get; set; }
public string Name { get { return Entity.UserName; } set {...} }
public string Email { get { return Entity.Person.Email; } set {...} }
{...}
}
This way you can bind the controls to the ViewModels properties instead of the entities properties, but it gets a bit hard to work with the change notifications.
You may also want to check: this toolkit. It solves this problem defining a wapper to your entity and using DynamicObject simulates an object that has all the properties from the wrapped one. This is a bit slow when working with large ammounts of data, but simplifies the work a lot.
Hope this helps.

Bi-directional view model syncing with "live" collections and properties

I am getting my knickers in a twist recently about View Models (VM).
Just like this guy I have come to the conclusion that the collections I need to expose on my VM typically contain a different type to the collections exposed on my business objects.
Hence there must be a bi-directional mapping or transformation between these two types. (Just to complicate things, on my project this data is "Live" such that as soon as you change a property it gets transmitted to other computers)
I can just about cope with that concept, using a framework like Truss, although I suspect there will be a nasty surprise somewhere within.
Not only must objects be transformed but a synchronization between these two collections is required. (Just to complicate things I can think of cases where the VM collection might be a subset or union of business object collections, not simply a 1:1 synchronization).
I can see how to do a one-way "live" sync, using a replicating ObservableCollection or something like CLINQ.
The problem then becomes: What is the best way to create/delete items?
Bi-directinal sync does not seem to be on the cards - I have found no such examples, and the only class that supports anything remotely like that is the ListCollectionView. Would bi-directional sync even be a sensible way to add back into the business object collection?
All the samples I have seen never seem to tackle anything this "complex".
So my question is: How do you solve this? Is there some technique to update the model collections from the VM? What is the best general approach to this?
Personally, I use an ObservableCollection in my model and my viewmodel.
class Model
{
public ObservableCollection<Foo> Foos;
}
class ViewModel
{
public Model Model;
public ObservableCollection<FooView> Foos;
public ViewModel()
{
Model.Foos.CollectionChanged += OnModelFoosCollection_CollectionChanged;
}
void OnModelFoosCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
Foo re;
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
re = e.NewItems[0] as Foo;
if (re != null)
AddFoo(re); //For other logic that may need to be applied
break;
case NotifyCollectionChangedAction.Remove:
re = e.OldItems[0] as Foo;
if (re != null)
RemoveFoo(re);
break;
case NotifyCollectionChangedAction.Reset:
Foos.Clear();
/* I have an AddRange in an ObservableCollection-derived class
You could do Model.Foo.ForEach(ree => AddFoo(ree));
*/
var converter =
from ree in Model.Foo
select new FooView(ree);
Reports.AddRange(converter);
break;
default:
//exercise for the reader :)
s_ILog.Error("OnModelFoosCollection_CollectionChangedDid not deal with " + e.Action.ToString());
break;
}
}
void AddFoo(Foo f)
{
Foos.Add(new FooView(f));
}
void RemoveFoo(Foo f)
{
var match = from f in Foos
where f.Model == f //if you have a unique id, that might be a faster comparison
select f;
if(match.Any())
Foos.Remove(match.First());
}
}
Now, when you remove something from the Model's Foo collection, it will automatically remove the corresponding FooView. This corresponds with how I think about this sort of thing. If I want to delete something, the Model is where is really needs to be deleted.
It feels like a lot of code, but it isn't that much, really. I'm sure one could build a generic version of this, but IMO you always end up wanting custom logic dealing with addition/removal of elements.
I too am struggling with the bi-directional sync of two collections for use with WPF via MVVM. I blogged MVVM: To Wrap or Not to Wrap? How much should the ViewModel wrap the Model? (Part 1) and MVVM: To Wrap or Not to Wrap? Should ViewModels wrap collections too? (Part 2) regarding the question, including some sample code that shows a two way sync. However, as noted in the posts, the implementation is not ideal. I would qualify it as a proof of concept.
I like the BLINQ, CLINQ, and Obtics frameworks that Alex_P posted about. These are a very nice way to get one side of the sync behvaior. Maybe the other side (from VM to Model) can be implemented via an alternate path? I just posted part 3 on my blog that discusses some of this.
From what I can see, bi-directional via BLINQ and CLINQ is not supported in cases where the LINQ statement projects the data to a new structure.
However, it does look like CLINQ may support Bi-Directional syncing in cases where the LINQ query returns the same datatype as the underlying collection. This is more of a filtering scenario, which doesn't match the use case of a ViewModel wrapping the data in the Model.
The only situation, when you might need the two-way synchronization, is when the control that you use to visualize your collection of VMs does not let you know of user's intention to create or remove an item. I.e. the control deals directly with your collection of VMs and the ONLY way you know the item has been added/removed, is by monitoring the collection of VMs. If this is not the case then you can implement one way sync and add/remove items directly on model's collection.
EDIT: Take for example WPF DataGrid
control bound to observable collection
of ItemViewModels. If its
CanUserAddRows property is set to true
and the user starts typing in the
empty row at the bottom, the DataGrid
will use default constructor of your
ItemViewModel to create a loose item
and then will add it to the
collection. There is no indication
from DG that it wants to add an item
the collection.c
I can't think of any
other control that is complicated
enough to be able to add items to
collection on its own.
The opposite
scenario is when you have ListView
bound to your collection and a command
which indicates user's intention to
add new item - then in command handler
you simply add new item to DataModel
and let the one-way sync do the rest of
the job. In this case ListView is not
able to add to the collection it
presents.
As to the sync process itself, look at Bindable LINQ project - it can minimize the amount code and improve readability. For example the code Tom posted will translate into something like this:
class ViewModel
{
public Model Model;
public ObservableCollection<FooView> Foos;
public ViewModel()
{
Foos = from foo in Model.Foos.AsBindable()
select new FooView(foo);
}
}
EDIT 2: After using B-LINQ for some time now I should say that you might have performance issues with it. I have used it to synchronize relatively big collections (hundreds of elements) collections with tens of elements being added and removed every second and I had to give it up and implement synchronization the way Tom had suggested.
I still use B-LINQ though in those parts of the project where collections are small and performance is not an issue.
I've written some helper classes for wrapping observable collections of business objects in their View Model counterparts here, maybe it should be extended to go the other way. always looking for contributions...
I have proposed a general Undo / Redo framework based in MVVM, that uses some techniques related to the problem you describe. It uses collections implementing this interface:
public interface MirrorCollectionConversor<V, D>
{
V GetViewItem(D modelItem, int index);
D GetModelItem(V viewItem, int index);
}
(V is for the ViewModel items, D for the model items)
Using this interface it automatically synchronizes the viewmodel collection when the model collection changes. If you change the viewmodel the change is simply redirected to the model collection.
The GetViewItem function gives you some flexibility in how the viewmodel objects are related to his model counterparts.
You can find the details here.
(I admit that the construction is quite complex and I will be very happy to listen to suggestions).
With my ObservableComputations library you can create ObservableCollection that is result of computing over another ObservableCollection and is synchoronized with it. You make standart operations (add, remove) on the source colection: computed Collection reflects all the changes:
Filtering<Order> expensiveOrders = orders.Filtering(o => o.Price > 25);
expensiveOrders.CollectionChanged += (sender, eventArgs) =>
{
// see the changes (add, remove, replace, move, reset) here
};
// Start the changing...
orders.Add(new Order(8, 30));
orders.RemoveAt(1);
orders[0].Price = 60;
orders[4].Price = 10;
orders.Move(5, 1);
orders[1] = new Order(10, 17);

Does MVVM violate DRY?

It seems that ViewModels that I make look suspiciously like other classes and they seem to require a lot of code repetition, e.g. in a current project I have:
SmartForm: Model that represents a data form to fill in, has properties:
IdCode
Title
Description
collection of SmartFormFields
etc.
SmartFormControlView View
SmartFormControlViewModel ViewModel
IdCode
Title
Description
collection of SmartFormFields
etc.
So my ViewModel is basically the same as my Model, just with all the OnPropertyChanged features for binding with the View.
It seems as I refactor and extend this that every little change I make to my model, I have to make a mirror change to the ViewModel.
This seems to violate a basic rule of patterns Don't Repeat Yourself.
Am I implementing the MVVM pattern incorrectly or is it just an inherent characteristic of MVVM that there is always a 1-to-1 repetition going on between Model and ViewModel?
I personally don't think it violates DRY since the model and view-model (I prefer the term presenter) don't point to the same information. For instance your VM and M both have a Title property, but your VM's Title property could also include validation, whereas your model's Title property could assume validity.
While it's true that The VM may contain all of the properties of the model, there is also the possibility of having validations (e.g. Title must be non-blank), data-dependencies, bindable UI-specific properties (icons, colors, brushes, etc.) which aren't part of the view.
Essentially all UI patterns have similar "duplication" in the way you state it: namely cascading modifications. Try changing a model in MVC without changing the controller.
That being said, MVVM (or any UI pattern designed to separate UI, logic, and state) can be overly tedious for simple cases such as your example. When logic becomes little more than state-pass through, the value separating the controller/presenter/view-model decreases.
In your specific case, if there really isn't any logic, validation, or UI specific properties that your VM isn't surfacing, and your model doesn't have to be persisted, serialized, or made backwards compatible with an existing structure (or adding the logic to do so in your VM is trivial), I would strongly consider combining the M and VM to avoid creating properties whose sole purpose is to get/set the underlying model's properties.
A simple solution is to have an abstract ViewModel(VM) base class that exposes the model. You can choose this VM in scenarios where it makes sense.
i.e.
public abstract class ViewModelBase<T>
{
public T Model { get; set; }
}
If you Model has INotifyPropertyChanged implemented your view will get the event. What this does do is give your View access to every property in your Model which isn't what you want some times.
also you can utilize property initializers like this(which I personally have stored in code snippets):
public abstract class SampleViewModel
{
public int MyProperty
{
get { return Model.MyProperty; }
set
{
Model.MyProperty = value;
OnPropertyChanged("MyProperty");
}
}
}
In most circumstances you view will be the one making changes to your VM and when it does any control that is bound to that property will then be told that something happened.
Hope that helps.
That's an interesting remark... indeed, it's often necessary to modify the ViewModel to reflect the changes in the Model.
It would be nice if it could be automatic... actually I think it could be possible, by implementing ICustomTypeDescriptor in the ViewModel : GetProperties would return all the properties of the model through reflection. However I'm not sure it would make sense, because the model may not consist of properties at all : it could be methods, fields, or anything, and not everything in the model would be useful in the ViewModel.
One thing that seems to have been missed here and that your simplistic example does not expose is the fact that your Views will often aggregate data that is contained within multiple Domain Model types. In this case your ViewModels will contain references to a number of domain Models (of differing types) thus aggregating a bunch of related data that a particular View may wish to expose.
Others have provided good comments on the roles of the components of the MVC/MVVM patterns. I would like to offer a fundamental observation explaining the repetitiveness no matter which pattern you select.
Generally there will be some sort of repetition between your data layer, business layer and UI layer. After all, in general you have to show each property to the end user (UI), model it's behavior (Business layer) and persist the value (data layer).
As others have pointed out, the property might be treated a bit differently on each layer which explains the fundamental need for some duplication.
When working on systems large enough (or on small projects with the right team), I tend to model this type of information in UML, and use code generation (often coupled with partial classes) to handle the repetitive aspects. As a simple example, the Last Name property might have a requirement (in my UML model) that it limit data to 50 characters. I can generate code to enforce that limit into my UI layer (e.g. by physically limiting input), generate code into my business layer to recheck that limitation ("never trust the UI") by perhaps throwing an Exception if the data is too long, and generate my persistence layer (e.g. NVARCHAR(50) column, appropriate ORM mapping file, etc.).
2012 Update
Microsoft's Data Annotations and their support in the UI layer (e.g. ASP.Net MVC) and on the data layer (Entity Framework) goes a long way toward implementing many of the concerns I previously generated code for.
Eric Evans, in his book "Domain Driven Design" mentions that Model refactoring should not be too hard, and that a concept change should not span into too many modules, otherwise, refactoring the Model becomes prohibitive, so, if you ask me, having the Model sort of 'copied' in the ViewModel certainly difficults Model refactoring.
Eric mentions that one should give more weight to Model cohesion and isolation, than to a tidiness in the division of layers based on technical concerns (database access, POCOS, presentation). That the most important concern is that the Domain Model is a good representation of the Business Domain, hence its the most important for the Domain Model to be in a single isolated layer, and not spanned in several modules, in order for it to be easily updated (refactored).
Considering what was just said, I'd use the same Model object in the ViewModel, and if I want to reduce the level of "access" to a Model object, then I'd "pass" a reference to an Interface implemented by the Model object. For example:
// The primary Model classes
public partial class OrderItem {
public int Id { get; }
public int Quantity { get; set; }
public Product Item { get; set; }
public int Total { get; set; }
public void ApplyDiscount(Coupon coupon) {
// implementation here
}
}
public partial class Product {
public int Id { get; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
}
// The shared views of those model classes
public partial class OrderItem : IOrderItemDTO {
public IProductDTO Item {
get {
return this.product;
}
}
}
public partial class Product : IProductDTO {
}
// Separate interfaces...
// You enforce the rules about how the model can be
// used in the View-ViewModel, without having to rewrite
// all the setters and getters.
public interface IOrderItemDTO {
int Id { get; }
int Quantity { get; set; }
IProductDTO Item { get; }
int Total { get; }
}
public interface IProductDTO {
string Name { get; }
string Description { get; }
decimal Price { get; }
}
// The viewmodel...
public class OrderItemViewModel {
IOrderItemDTO Model { get; set; }
}
I only know MVC and in MVC a Model-Class which contains GUI is some error. SmartForm seems to be a Form, which means it is not a model. I don't know what you are trying to program but I give you an example for a Model:
Take a Calender. You can ask the Class what date it is today, what month, how many days each month has, ...
It has no graphical representation though. The View (CalenderViewMonth or whater you want) prints a single Month on screen. It knows a Calender and asks him what to write in the different cells.
Essentially - you might have something wrong in your modeling / understanding of MVVM (which is a modern .NET-Variant of MVC).
Edit:
I just looked up MVVM on Wikipedia. Model is just like the Model in MVC. View like the View in MVC as well - only graphical representation. the ViewModel is the Glue between a generic View and a specialized Model. Some kind of Adapter. There should be no violation of DRY.
I think that yes, vanilla MVVM does violate DRY. But I've started the PDX library which I think can solve this problem in many cases. I wrote this post which I believe addresses this question.
Basically, my goal (one of them) is to have Viewmodels that don't worry about UI Notification. The PDX project is still in its infancy but if you're reading this question you might find it useful, and I would appreciate any feedback you may have.

Resources