It is not uncommon in the world of web programming to see a new acronym floating around every other week. I saw MVVM for the first time a few months ago, but I put off really learning what it was, I was focused on other things and since all the conversation pertained to its use with SilverLight and I was not focused on SilverLight at the time I put it on the list of things to look at.
Then I attended the ASP .NET MVC FireStarter in New York city where they talked about the ViewModel pattern being used for MVC applications. I immediately saw the benefits of this pattern with respect to Microsoft Entity Framework as it took the hassle out of the lost/unloaded context problem I had to circumvent whenever using the framework. I was able to fully create a set of objects that translated the generated entities into classes that could be efficiently used by the View, in addition, I found added benefits from having these classes inherit from each other. And since every OO programmer is continually striving for a way to reuse as much as possible without creating too much complexity, this was a win in my opinion.
What I did not realize at the time was, this is the essence of the MVVM pattern that has been gaining popularity. It happened recently when I was thinking about the application I am developing for the client out here in New York. I realized that in fact I had architected the application to follow this pattern without even realizing it. As is the case whenever you realize such a thing, you start wanting to refactor bits that you did not design according to the pattern, without taking too much time in doing so. I have a number of cases that I am correcting where we are using anonymous objects where we could be using these “proxy” objects as I call them, but they really are ViewModels, I am even starting to create facades for other objects that are composites of other properties within the object.
What I did was I had Linq2Sql generate a bunch of classes based on the tables we are using, each of these classes is proceeded by either a t (table) or a vw (view). The ActiveRecord pattern is used to make these calls into the model, thereby creating a clean separation that allows data access calls to be refactored without changing calling code. At the start, we were returning the data from these calls to the View via anonymous objects. (reasons for using this architecture where mostly due to using the Coolite ExtJs ASP .NET UI Framework). However, as we began to develop the controllers which handled the brunt of the more involved functionality, I began creating classes for use by these controllers. It became almost instantly apparent that these classes could also be used in the Read calls. And now, I am rewriting old code to use objects themselves. The value of this was recently demonstrated when the client asked for a formatting change that required a minimal to change, but the effect was application wide.
The one thing I would like to do differently next time, is make the static methods use to call into the model hang off the view model objects instead, this way there is no visible usage of the generated model classes, this is how my current personal application is setup, though it uses a service based pattern for data access, this is the recommended approach when using a context driven ORM as is the case with Linq2Sql or EF. I have handled the cases in which I want to share my context across many functions (for transacted scenarios) by creating internal functions that can accept an existing context as a parameter, though it is only visible within the assembly it is defined in, this keeps calls in the view from being able to see these functions, thereby hiding the use of a context reference entirely from the view.
The idea of taking the static methods off the generated views and onto the view models themselves is that, like the service pattern, the translation is shared and not implemented all over the place. This means that if you want to change a property that needs to come back, you do it in one spot. For custom queries, you can still define the custom translation in a custom view model. But the point is that you can better control over your translation which helps with maintenance and code cleanliness. One of the ways I am doing this now is creating constructors that build the ViewModel objects for me. But if I can find the time to perform this refactor, it is something I will do. The other concern is that I am training other developers to develop this application, so I need to be careful changing patterns on them.