locked
Communication between ViewModel and domain model RRS feed

  • Question

  • Here's a question I bet you don't get every day.

    I am building an app that uses Model-View-ViewModel and Domain-Driven Design. Basically, the ViewModel wraps various domain model classes using a GoF Adapter pattern. The reason for using this pattern is that the back end of my app uses NHibernate for ORM, and NHibernate only works with POCO objects--specifically, it limits collections to IList<T>--no ObservableCollection<T> or BindingList<T> collections allowed.

    Separating the domain model from the ViewModel also makes sense from a architectual standpoint. The ViewModel is concerned only with presentation. It doesn't try to do double duty as a domain model. The domain model is concerned only with modeling the problem domain. It doesn't try to do double duty as a Presenter. For that reason, I have avoided the custom collection types that fool NHibernate into thinking they are IList<T> and fool WPF into thinking they are ObservableCollection<T>.

    Here is how the domain model and the ViewModel fit together: Consistent with the Adapter pattern, each ViewModel object wraps a corresponding domain model object. When the VM object is created, it is passed a domain object, which the VM uses to set its properties. Non-collection VM properties are dependency properties, and changes to these properties are propogated back to the domain model object by PropertyChanged callback methods. Collection properties in the VM are ObservableCollection<T>. The ViewModel object handles the CollectionChanged events, and uses these event handlers to propogate collection changes back to the appropriate  collection property on the domain model object held by the VM.

    This approach works pretty well. It ensures that any change to a ViewModel object gets propogated back to the corresponding domain model object. But it has a weakness: If changes are made to a domain object after its VM object is created, the change doesn't propogate forward from the domain object to its ViewModel wrapper.

    Normally, the fix would be simple. I would simply make domain model collections ObservableCollection<T>, and have the VM subscribe to the CollectionChanged event of the DM. But I can't do that in this case, since NHibernate limits me to IList<T> collections in my domain model.

    Maybe it won't be a problem. The general data cycle is database -> domain model -> ViewModel -> UI, where the user makes a change, then the reverse path back to the database when the change is committed. I don't really anticipate changing the domain model after it has been bound to a ViewModel. The only changes should be those made by the end user, which propogate from the ViewModel back to the domain model.

    So, my problem is how to propogate a change to a collection property on a domain object, made after the object is bound to a ViewModel object, forward to the ViewModel object, given that the domain collection property is required to be an IList<T>.  

    Now, here's my question: Has anyone else come across this problem? How did you handle it? Is this even worth worrying about? Thanks for your help, and you get the Obscure Question of the Day award.

    David Veeneman
    Foresight Systems
    Monday, March 23, 2009 7:38 PM

Answers

  • Okay--here is one possible solution. If the domain model is updated by the app back end after the domain model is bound to a ViewModel, the app back end has to call an Update() method on the ViewModel. The Update() method will force the ViewModel to re-read the domain model objects that it holds and reset its properties acordingly.

    I'm thinking the back end would have to call the method on the ViewModel object--I can't add an event to the domain model, because there is no way to implement change notification on the domain collections while retaining IList<T> typing.

    Any comments on this solution, as well as other solutions, greatly appreciated.

    David Veeneman
    Foresight Systems
    Monday, March 23, 2009 8:01 PM