Saturday, 5 November 2011

Silverlight, Prism & MEF

In my latest project I’ve been working with Silverlight (version 4), in conjunction with Microsoft’s Prism framework, and the Managed Extensibility Framework (MEF). Prism was designed by Microsoft's Patterns & Practices group, and is also sometimes known by the somewhat less catchy title of “Compososite Application Guidance”. It's a generalised framework for composing UIs in WPF and Silverlight that are comprised of loosely-coupled parts. It makes use of patterns like Dependency Injection / Inversion of Control to achieve loose coupling between the various constituent components of a solution. This means that those components can be designed by teams working in isolation, and leaves the design open to be extended in the future. Whilst Prism itself isn’t specifically tied to the MVVM pattern, the loose coupling it enables is typically used by developers working in Silverlight or WPF as a mechanism to help implement that pattern, and to thereby leverage the testability and extensibility benefits that MVVM bestows. My current project has also provided some other interesting challenges for me, in the form of technologies that I’ve been encountering for the first time in a live project. Specifically, for reasons related to the product itself, the project I’m working on utilises several Postgres databases running within a Linux environment – not an everyday challenge for a .Net developer by any means. This blog entry provides a brief overview of the above toolsets, and their purpose within the overall design.

MVVM (Model View ViewModel) is a development pattern that was first proposed by John Gossman, and is based on an even earlier pattern by Martin Fowler called the Presentation Model. I wont attempt to describe MVVM in full here (there are a great many other articles available on the web that do that far better than I could, for example this one here, as well as useful training videos that give you an introduction to some actual coding techniques to implement the pattern. More on those later.) For the purposes of this blog, I’ll just summarise by saying that MVVM is a pattern that takes code that would ordinarily reside in code behind files, and pushes that code into separate areas of the application known as ViewModels. The code that resides in these separate ViewModel classes represents the pure business logic of the application. This is where the pattern starts to become useful in ways that have made it the most popular and widely-adopted approach for extensible WPF and Silverlight applications. Separating concerns in this way makes the ViewModels in which the business logic resides independently unit testable, which in turn makes the design more resilient to ongoing development and change. So, any developers that need to alter the design in the future after initial development has been completed and the product is in a care and maintenance phase can have greater confidence that any changes they may implement will not break existing code. 

Prism: Not the only option for implementing MVVM
Prism isn't the only option for implementing the MVVM pattern. There are many alternative MVVM frameworks out there, e.g. the MVVM Light Toolkit. As noted, Prism version 4 isn't in itself tied to MVVM in any way. It’s just a generalised framework for designing extensible, composite UIs that exhibit loose coupling. However, the loose coupling that Prism provides is commonly used by WPF and Silverlight developers as an enabling mechanism for implementing MVVM. Which framework and pattern you may choose for a given solution is entirely a judgement call. Prism and/or MVVM may well be over-complicated for some types of simple application. Just because you're working in WPF or Silverlight, doesn't mean you should de facto be using Prism, or implementing MVVM. There are overheads involved in deciding to use each, and it's worth noting that they won’t be the right choice for every single project that uses those technologies. Even John Gossman himself has suggested that some of the approaches that MVVM facilitates may be overkill for simpler applications that are not intended to be long-lived, extendable or scalable. Prism contains a great many discrete features for building composite UIs. (e.g., it provides a selection of Navigation frameworks, the ability to group individual Views into Regions and Modules, has integration with the separate Unity or MEF components for Dependency Injection, and even facilitates the option to use your own preferred DI framework of which there are literally dozens of options if you prefer, as well as features such as its Event Aggregator which facilitates communication between loosely-coupled components in a way that leaves the publishing and consuming components freely independent of one another). However, what's nicest about Prism is that developers are free to pick and choose which specific parts of that significant set of features they will use for their own particular solution. You don’t have to use it. And, if you do choose to, you’re not forced to use it all.

When implementing MVVM, Prism may be used in a range of discrete ways to facilitate reliable, scalable results in a reasonable amount of time.
I wont go into all of Prism’s more discrete areas that I touched upon above within this blog, but can recommend this excellent guide to Prism in conjunction with this equally-enlightening guide to Silverlight 4 development for further reading. The Prism guide is part-written by the lovely Ward Bell, whose insightful videos on IdeaBlade’s DevForce ORM tool gave me many an enlightening chuckle a few years back. Get ’em on Kindle so that you can read them on your PC instead of lugging heavy books around – you know it makes sense. ;) 

Before moving on from this discussion of Prism and MVVM, I'll just lastly note that there's a great little series of instructional videos by Microsoft's Mike Taulty available. 

It's a rare individual that can grasp technical concepts clearly, and communicate them to others. Mike manages to do so beautifully over the course of just a few hours. His videos are great for getting a feel not just for what Prism and MVVM can do, but also along the way they give quite a bit of insight into how composite applications can be more complicated to understand than traditional, tightly-coupled designs. And they demonstrate how easy it is to build up an illusion of loose coupling using frameworks like Prism, whilst in realty just turning turning tight coupling that would otherwise cause build errors at design time into breaking functionality at runtime that are harder to track down and eliminate from the design. When you get to the part of the videos where Mike is having to copy DLLs into bin folders by hand to ensure that the project still works as expected you'll see what I mean.
I appreciate that Mike's videos do contain some contrived examples, but still voluntarily immersing yourself back in the Bad Old Days of DLL Hell isn't what any pattern or practice that's meant to make developers’ lives easier should be about.  That illusion of loose coupling whilst really still having all the same interdependencies of tight coupling in disguise is also evident when Mike doesn't attempt to type in the XAML configuration files that describe how his Modules should be loaded and what dependencies they will have on one another. He instead stops the video when it gets to those points and gets said config files from a Blue Peter -stylie pre-prepared example, because in his own words typing in such config files by hand is “prone to error”. It's ridiculously easy to get such configuation information wrong in ways that will only become apparent when a user tries to use the components controlled by them at runtime. And it's even easier to get the configs right in the first instance, but for them to become invalidated at some later point during the lifetime of the extensible application involved by later development work. It's a judgement call for the developer/architect to make as to whether the risks vs rewards of using Prism make using it the right decision for a given project.

Getting back to MVVM as a concept in its own right, as I mentioned the last time I wrote about Silverlight, one of the main strengths of and purposes behind the XAML-based design environment that each of these technologies uses is the separation of concerns that XAML facilitates between the related but distinct goals of design and development. Using XAML as a common medium allows designers that are primarily concerned with the look and feel of an application to work hand-in-hand with developers, whose primary responsibility is making sure the application actually does what it was functionally intended to do. MVVM adds a further refinement to that collaborative effort within WPF/Silverlight. It enables developers to protect their work against any unintended behaviour that may be introduced after initial development, by allowing their business logic code to be unit tested in isolation from the purely visual elements of the solution. For designers, MVVM allows the visual elements that they are most interested in (called the Views) to be designed independently from the application state and business logic stored in the ViewModels. In the case of designers, using MVVM is also useful for simulating application state at design time, thereby allowing them to refine the visual representation that the UI will be required to have when it experiences those states when the application actually runs. The final part of MVVM – Models – concerns those parts of the application that are purely concerned with the business of communicating with whichever specific back-end database is being used. This is particularly useful in allowing developers to focus on business logic in isolation, without becoming overly-involved in issues that are more generally within the purview of DBAs.

Some clichés about Web Designers
and Developers. And Women.
Designers use a tool called Expression Blend to work on the visual elements of WPF/Silverlight applications. As a developer, you can think of Blend as a great big Photo Shop for Visual Studio 2010. It allows all those subtle little visual effects that differentiate between professional and amateur software products to be applied to functional designs in a way that takes those designs from being merely useable to being useable + refined. One of the first problems that users of Blend typically experience when working with .Net projects is that any moderately-complex business logic that is tightly coupled with UI elements has a fairly high probability of completely breaking Blend. Typically, problems that will break Blend in this way include things like database connectivity that is not available at design time being required to provide data for the UI Element’s initialisation. Since Blend semi-initialises components in order to render them in its design surface, this presents an additional challenge for developers. If you’re a developer user of Blend, initialisation issues of the type described are just about a manageable problem, since it’s possible to attached Visual Studio’s debugger to the Blend executable using Visual Studio’s “Debug -> Attach to Process…” feature, and thereby discover at precisely which point in the code Blend is failing to render a given control. Fixes to such problems will typically involve using C#’s System.ComponentModel.DesignerProperties.IsInDesignTool Property to intelligently protect those areas of code that are erroring out. For designers, who typically don’t touch the underlying code, this issue can present more of a brick wall – if there’s an area of code underlying a UI element that they need to style that doesn’t work, they’re pretty much stuck without a developer’s help.

By using MVVM, any code that UI Elements use can be separated out into their own classes (called ViewModels). By separating concerns in this way from the outset, it makes it less likely that UI Elements will be fundamentally unable to be rendered in Blend at design time. Most MVVM frameworks will render any constructor logic within a base ViewModel class that utilises the DesignerProperties.IsInDesignTool Property mentioned above within a common base constructor. By solving this problem once and for all, and avoiding rather than dealing with the consequences of designtime / runtime issues of this type, MVVM helps to significantly reduce the number of occasions when design members of the team will have to call on busy developers for help.

Concentrating on the developer-centric benefits of MVVM, by separating out business logic code into ViewModels developers obtain in return greater control over the stability and testability of their functional code. If you’ve worked on a software product of any level of complexity with a moderately-sized team, you’ll know that there is ample scope for code that has been written, debugged and tested to begin experiencing unanticipated behaviour at some later point in the development cycle, through no fault of the original developer or tester. Developers that are starting out (and even some that have been around long enough to know better!) are sometimes misguided enough to believe that their own code is bug-free.
This is usually not the case, but, even if we were living in some mythical Nirvana universe where we were all super-developers that produced error-free code first time every time, there is still ample scope for any developer of any level of ability to have bugs inadvertently introduced into their code by other team members as the collaborative software product you’re building together evolves over the course of the project. This is where the Unit Testing that MVVM facilitates becomes useful. Just to make my position clear on this subject: I’m not an advocate of what I would term ‘fundamentalist’ Test Driven Development. Which is to say that I don’t advocate the approach to TDD that involves writing tests before writing code, or that encourages writing lots of meaningless tests for even the most simplistic parts of the system. I do, however, support the concept of writing tests to protect existing human-tested code against unanticipated bugs being introduced by subsequent development. MVVM allows various frameworks such as the Managed Extensibility Framework (MEF) and Unity to work in conjunction with Unit Testing and Mocking frameworks such as xUnit and Moq to test ViewModels in isolation at design/test time. This allows developers to set up unit tests that automate the process of confirming ‘What should happen if…’ scenarios. [And, in the case of MEF, there is also lots more functionality on offer, including the ability to group loosely-coupled independent components of the solution into a coherent composite application. You can find lots of good info about how to use MEF in conjunction with Silverlight here. ]

Well, so much for this overview. I’m enjoying working with Prism, as well as the other tools/environments that I mentioned such as Postgres and Linux for the first time, and thereby evolving into an ever-more-experienced developer with first-hand insight into how a range of technologies are being used on live projects. As the name of this blog suggests, it’s not just the code or the software products that I’ve been involved in building over the years that’s a Work In Progress, it’s myself and my professional experience that are ever-evolving. One of the things that makes that process of learning and personal development possible is having a great team to work with in a positive and forward-thinking environment. I’m very pleased to be working with such a knowledgeable team at this time, who have many strengths in those areas that are newest to me, and are open enough in their outlook to allow my ideas and discrete experience to be part of their already-impressive mix too.