views:

267

answers:

2

I have stateless services and anemic domain objects on server side. Model between server and client is POCO DTO. The client should become MVVM. The model could be graph of about 100 instances of 20 different classes. The client editor contains diverse tab-pages all of them live-connected to model/viewmodel.

My problem is how to propagate changes after server round-trip nice way. It's quite easy to propagate changes from ViewModel to DTO. For way back it would be possible to throw away old DTO and replace it whole with new one, but it will cause lot of redrawing for lists/DataTemplates.

I could gather the server side changes and transmit them to client side. But the names of fields changed would be domain/DTO specific, not ViewModel specific. And the mapping seems nontrivial to me. If I should do it imperative way after round-trip, it would break SOC/modularity of viewModels.

I'm thinking about some kind of mapping rule engine, something like automappper or emit mapper. But it solves just very plain use-cases. I don't see how it would map/propagate/convert adding items to list or removal. How to identify instances in collections so it could merge values to existing instances. As well it should propagate validation/error info.

Maybe I should implement INotifyPropertyChanged on DTO and try to replay server side events on it ? And then bind ViewModel to it ? Would binding solve the problems with collection merges nice way ? Is EventAgregator from PRISM useful for that ? Is there any event record-replay component ?

Is there better client side pattern for architecture with server side logic ?

+1  A: 

Typically, I've kept a reference to the DTO in my Model classes. For multiple models, I ensure each model knows how to construct itself from a DTO, as well as how to Save itself using an injectible "saver" or other service provider object. Carrying around a reference to the DTO makes it pretty easy, when you call Save() on the model, to modify the old DTO according to the Model before passing it back to the service.

Hopefully any "updates" to other objects after a Save() operation could be communicated in other DTOs, which should then be loaded into the appropriate Model classes used by your ViewModel.

The downside to this is that you do indeed have to write the mapping code, but this is usually the easiest part. I am not convinced this is the best way to do things and I would appreciate reading others' responses.

Patrick Szalapski
This is my default approach in this situation. Typically the update after Save() is triggered via server event, each model can then update itself from changes triggered by the DTO change.
Steve Jackson
A: 

I used another variation with a lot of success. We had a real-time GUI, so repetitive redraws on the client were not acceptable.

We made our DTOs aware of their property changes, and emit PropertyChanged events to the ViewModel, therefore replaying server-side events.

Code is straightforward to write, unit test, etc. It becomes easy to browse when PropertyChangeListeners (interfaces implemented by ViewModels) are typed.

This boundary can also be used to switch threads to the GUI worker thread.

louisgab
I'd be apprehensive about doing this. The value of having DTOs is that they have one concern--transferring data across a service boundary--and can be optimized for that purpose. No methods, no parameterized constructors, no events--these are domain object/model concerns. I've had one WCF project where we used our domain objects as DTOs. It worked pretty well, until we needed constructor logic to initialize (which didn't run since WCF uses property initialization). This kind of thing snowballed into more and more stupid domain concerns interfering with our DTO and vice-versa. Yuk.
Patrick Szalapski
You made me realize my particular project got lucky... we did get the occasional conflicting requirements between DTO and domain, but we were able to keep them orthogonal within the DTO classes.
louisgab