MVVM: Filling the Pattern Gap in Silverlight Application Development Bart McDonough Principal Consultant Incline Technical Group Bart McDonough • Principal Consultant, Incline Technical Group • Specialize primarily in SharePoint (MCTS) but also work a lot with Silverlight and ASP.NET • Introduced to MVVM in mid 2009 while developing commercial Silverlight application • Avid hiker and skier! Quick Poll • I read somewhere that polls make presentations more interesting… What I’m Covering • • • • • Overview of MVVM MVVM Break-down (M, V, VM) Implementing MVVM Testing with MVVM MVVM Frameworks Questions are welcome any time during the presentation! About the Demo App • The “Book Club” application • Originally developed by John Papa – Sr. Technical Evangelist at Microsoft – Check out his blog at johnpapa.net • Was created to demonstrate various concepts in Silverlight such as RIA Services and MVVM • I grabbed it from Papa’s blog, tweaked the UI, and added some basic unit tests What is MVVM? • Model-View-ViewModel • Belongs to a class of patterns known as “presentation” patterns – Same class of patterns as MVC & MVP – Adapted from the “Presentation Model” pattern • Goals – Cleanly separate application logic from the UI (the “view”) – Make “multi-role” development easier – Make it easier to test, maintain, and reuse code – Leverage core capabilities of WPF & Silverlight like data binding, templates, commands, and behaviors Just in Case You Care… • John Gossman, a WPF/Silverlight architect at Microsoft, is credited with creating MVVM back in 2005 • Originally created for WPF and was later adapted for Silverlight Why was MVVM Created? • Created in response to WPF/Silverlight – Multiple roles (designers and developers) may work in parallel on different pieces of the same application – Desire to leverage core capabilities in these new technologies • But what about the “pattern gap?” – Traditional presentation patterns (e.g. MVC & MVP) are developer-centric, creating a “gap” when designers are involved – Also, those patterns weren’t designed with WPF/Silverlight capabilities in mind Can I See a Pretty Picture? Sure, here you go… View (XAML) Data Binding and Commands/ Behaviors ViewModel Notifies view of changes (INotifyPropertyChanged or INotifyCollectionChanged) Model MVVM BREAK-DOWN MVVM - Model • Domain object (representation of your business data) • May contain validation (e.g. data annotations used with RIA Services) • May be directly exposed in view model for binding – In which case it needs to implement the usual binding interfaces Example of Models • XML data file • List of Employee records being submitted to a WCF service • LINQ to SQL entity retrieved from a database • Contact record (POCO object) MVVM - View • Defines structure and appearance of what user sees on screen – Examples: Window, page, user control, or data template • In MVVM, views should be expressed primarily in XAML – Code-behind contains only InitializeComponent() plus UI code that’s impractical to represent in XAML or requires direct references to UI controls MVVM - View Model • • • • • “Glue” between model and view Presentation logic and view state No direct reference to view Notifies view of property/state changes Essentially consists of code that would typically be found in code-behind + logic involving loading, saving, and preparing model data for display • Typically calls into some sort of service layer to load/save model data (e.g. WCF) Benefits of MVVM • Separation of concerns • Developers and designers can coexist in harmony • Makes unit testing easier • Reduces repetitive/mundane code by using data binding • Improves maintenance and scalability Some Typical Concerns • What about navigating between pages/views? • How do I allow one view model to communicate with another? • What about my services for loading/saving data? How do I hook into those? • All of these can be addressed while still maintaining separation of concerns Addressing the Concerns • Navigating Between Views – Navigation “Service” • VM-to-VM Communication – Loosely coupled messaging (publish/subscribe model) • Hooking into Services – View models should not contain service logic (WCF calls, etc.) – Break out services into their own classes – Can further abstract with a “provider” that allows a live service to be “swapped out” at design/test time “Religious” Questions • These tend to spark a lot of debate… – Where’s the “dividing line” between the view and the view model? What code goes in each? – Must the code-behind file be 100% empty except for the call to InitializeComponent()? – “Chicken and the egg” – a.k.a. the view and the view model – which comes first? Does the view instantiate the view model or the other way around? LET’S DIVE IN: IMPLEMENTING MVVM Demo • Let’s examine: – How the view model is hooked into the view – The role of a view model “locator” class – How navigation and services are tied in with the view model – How we implement INotifyPropertyChanged Dealing with Interactivity • Silverlight 4 introduces support1 for the ICommand interface – Supported on ButtonBase class (and therefore all controls that derive from it) and HyperlinkButton – Members • CanExecute (property) • CanExecuteChanged (event) • Execute() • What about other controls that don’t natively support ICommand? ICommand was present in Silverlight 3 as well, but no controls natively supported it. Therefore, it wasn’t very useful unless you wrote code to support it yourself or used a 3rd-party framework. 1 Behaviors • Introduced with Expression Blend 3 • A “behavior” is a reusable piece of interactivity that can be applied to a UI element • InvokeCommandAction – System.Windows.Interactivity DLL – Comes with Expression Blend 3 or 4 • EventToCommand – Comes with MVVM Light Toolkit – Can be added to any FrameworkElement • Downside is these involve extra markup and additional DLL references Behaviors, Cont. • Silverlight 5 introduces custom markup extensions, which will allow you to do the same thing in one line of XAML with no additional DLL references • Meanwhile, here’s a good rule of thumb for Silverlight 4 (courtesy of John Papa) – Use a command if it’s available – Otherwise, use a behavior Why Commands/Behaviors? • In MVVM, the goal is for the view model to contain logic that is “invoked” from the UI – Traditionally, this would’ve been the job of the code-behind file • Commands and behaviors allow us to achieve this – They “directly” connect the UI and view model, bypassing code-behind Demo • Let’s examine: – Commands • How are they registered, and how are they used? – Behaviors • How does a behavior look in XAML compared to a command? Unit Testing with MVVM • Silverlight Unit Test Framework – Available as part of the MS Silverlight Toolkit (CodePlex) – The toolkit uses the framework for its own unit tests – Severely under-documented, so take a look at the toolkit’s own unit tests • Nifty Features – Can be run directly within the browser – Tests can be “tagged” – Support for testing asynchronous calls Demo • Let’s examine: – How to create a Silverlight unit test project – How some simple unit tests might look – How to run the tests Unit Testing, Cont. • Could also use a “mocking” framework such as Moq – http://code.google.com/p/moq • Could also use a unit test automation framework like StatLight – http://statlight.codeplex.com How a Non-Async Run Looks Diagram from Jeff Wilcox’s blog: • http://www.jeff.wilcox.name/2009/03/asynchronous-testing How an Async Run Looks Diagram from Jeff Wilcox’s blog: • http://www.jeff.wilcox.name/2009/03/asynchronous-testing When Should I Use MVVM? • When it makes sense – weigh the time and cost against the benefits • You don’t have to use MVVM on every single Silverlight project – Remember, it was conceived with largescale “multi-role” projects in mind – Could be overkill for super simple UIs • However, using it even just a little bit can reap some benefits Remember… • You need to know XAML • MVVM relies heavily on data binding – You need to understand how data binding works, especially in XAML • Patience is recommended – For debugging data binding issues – However, this will get better in Silverlight 5 • There is no single “right way” to do MVVM… it’s a pattern, not an implementation Frameworks • • • • Caliburn MVVM Light Toolkit Calcium Prism 4.0 – Microsoft’s Patterns and Practices library for Silverlight and WPF – Not an “MVVM framework” but includes components and guidance that aid in implementing MVVM • Onyx (WPF Only) • WPF Toolkit (Obviously WPF Only) – Includes WPF Model-View-ViewModel Toolkit Contact Information Bart McDonough Email: bart@inclinetchnical.com Blog: doseofdotnet.wordpress.com Twitter: @bartmcdonough Company: www.inclinetechnical.com THANK YOU!