Implementing the MVP Pattern in Silverlight

Silverlight 2 is the next major update of Microsoft’s Rich Internet Application (RIA) technology. It includes a cross-platform, cross-browser version of the .NET Framework, that enables a rich .NET development platform that runs in the browser . The recent release of Silverlight 2 Beta has given developers the opportunity to start developing rich internet applications using Visual Studio. So now that we can develop rich client applications in Silverlight, how can we architect a Silverlight application in a way that allows us to effectively unit test our code? The Model-View-Presenter design pattern can help to achieve this.

The MVP Pattern

The Model-View-Presenter (MVP) pattern separates user interface logic into testable components. This pattern is commonly used in ASP.NET applications to improve the testability of presentation logic. The same principals can be applied when developing applications in Silverlight 2.

MVP Pattern

There are many articles that explain the principals of the MVP pattern, so I won’t go into detail here. If you are unfamiliar with the pattern, a good introduction can be found here.

Basically, the MVP pattern consists of the following components:

Model – Represents the domain data.

View – Contains the user interface.

Presenter – Manages presentation logic and data binding.

User interface code can be difficult to test as it is usually tightly bound to controls. Separating the code from the view allows presentation logic to be more easily tested.

This separation also allows us to reuse presentation logic throughout an application. If an application contains different views of the same data, we only need one presenter to manage each view.

Unit Testing Silverlight Applications

One of the great benefits of the MVP pattern is that it allows you to unit test your presentation logic. Unfortunately, I struck some problems while attempting to unit test code written in a Silverlight project.

Visual Studio will not allow you to reference a Silverlight assembly from a standard .NET assembly. This causes a problem as unit testing frameworks, such as NUnit, are standard .NET assemblies.

The following error occurs when attempting to add a reference to NUnit in a Silverlight class library project:

“You can’t add a reference to nunit.framework.dll as it was not built against the Silverlight runtime. Silverlight projects will only work with Silverlight assemblies.”

image2.png

This is understandable, as standard .NET assemblies may use framework features that are not available in the compact version of the .NET Framework in Silverlight. So, what if we add a reference to our Silverlight code to a standard .NET class library project? Well, we are then presented with this error:

“Silverlight projects can only be referenced by other Silverlight projects.”

image1.png

Again, this is understandable for deployed code, as the Silverlight application may be using features specific  to the Silverlight framework. But our unit test code shouldn’t contain any Silverlight-specific features.

So how can we unit test our Silverlight code if we can’t reference it from a test fixture? Well, I discovered that it is possible bypass the project reference and add a direct reference to the Silverlight DLLs from a standard class library project! This allows us to unit test the Silverlight presenter assemblies using NUnit, or any other .NET unit testing framework.

You may also find you have to reference a few Silverlight framework assemblies, such as System.dll and System.Windows.dll, but if you minimise references to Silverlight-specific features in the presenter classes, this shouldn’t be a problem.

Microsoft have announced a Unit Testing framework for Silverlight 2. There are no details on this yet, but I would be surprised if it supports third-party testing frameworks, such as NUnit and mbUnit, or mocking frameworks, such as NMock and RhinoMocks. I could be wrong though, but until then, this method seems to work just fine.

So, now that we can unit test our Silverlight code, what is the best way to architect a Silverlight application? Well, I’m sure, like any application, it depends on your project. I develop ASP.NET applications and constantly find it difficult to unit test interface logic stuck in code-behind files. This problem seems apparent in Silverlight too, as the code-behind is tightly coupled with the XAML view. We can break this coupling and split our user interface logic into separate, testable components using the MVP Pattern.

Applying the MVP Pattern to a Silverlight Application

The following describes a conceptual model for a Silverlight application implementing the MVP Pattern. 

architecture.png

Server Application

The main database, domain model and business logic reside on the server.  The data and business logic is accessed by the Silverlight application through calls to Web Services. The server application can be architected independently and is not specific to the MVP Pattern.

Silverlight Client

The Silverlight client application contains only presentation logic and no business logic. Any operations that require business logic should be passed back to the server to be processed and results returned in the form of a Data Transfer Object (DTO).

Service Reference

The Silverlight application talks to the server via web services. Visual Studio creates a service reference that contains methods for making asynchronous calls to a web service. We can create a partial class from the generated service soap client that implements a custom interface containing methods used by the presenter. We can then call service methods through this interface rather than directly referencing the service class. Using an interface also allows us to stub-out the service when unit testing the presenter.

Proxy Model

When the Silverlight application references a web service, a proxy data class is generated. This class acts as a Data Transfer Object (DTO) that represents a data structure for transferring data between the client and server applications. The DTO provides the model used by the view and presenter.

View

The view is the visual representation of the application.

The view is composed of XAML files and their corresponding code-behind files. This structure is very similar to that of an ASP.NET page.

The XAML files describe the layout and behavior of the Silverlight interface. Controls in the view are wrapped by properties in the code-behind file. Any events fired from controls are handled in the code-behind and passed up to the presenter for further processing. The presenter can also pass information back to the view through properties and methods in the code-behind.

Presenter

The presenter sits between the view and the service reference. If the view requests data, the presenter will call a service reference and present the results to the view. If an action requires logic, the presenter will handle the event and process the information to send back to the view.

Example Code

As an example, I have created a Silverlight application that implements the MVP pattern to display data from the Customers table in the Northwind database. The data can be edited and saved back to the database via a web service.

image3.png

image4.png

The solution contains the following projects:

Server Projects (Standard assemblies will reside on the server)

SilverlightMvp.DataAccess - Provides data from the Customers table using Linq to SQL.

SilverlightMvp.Web - Contains the web site that will host the Silverlight application and web services that the Silverlight application will call to access the customer data.

Client Projects (Silverlight assemblies that run inside the browser)

SilverlightMvp.View - Contains the XAML and code-behind files.

SilverlightMvp.Core – User Interface logic classes, including the presenters, service references and interfaces.

SilverlightMvp.Core.UnitTests – While not deployed to the client, this standard .NET assembly tests classes in the SilverlightMvp.Core project.

You can download the example code here

I hope this information is useful to anyone developing .NET applications in Silverlight. If you have any questions, comments or suggestions please let me know. Enjoy!

About these ads

29 Responses to “Implementing the MVP Pattern in Silverlight”


  1. 1 alkama May 5, 2008 at 11:57 am

    Thank you for your explanation

    if you can explain me how do you do to add a reference to a silverlight project

    Best regards

  2. 2 alkama May 5, 2008 at 2:47 pm

    thanks

  3. 3 timross May 5, 2008 at 4:22 pm

    Hi Alkama. You can reference a Silverlight project from a standard .NET project by adding a reference to the Silverlight project’s DLL, rather than to the project. You may also need to include references to some of the Silverlight system files, such as System.dll and System.Windows.dll. This will allow you to access functionality in a Silverlight project from a standard .NET project. Hope this helps.

  4. 4 openlandscape May 7, 2008 at 3:30 pm

    Thank you very much for the extremely informative & concise post.

    On a related note: Is there anyway that we can reduce the SOAP web service call load between the SL UI
    and the server web service? I mean, it looks like in this scenario you’d ideally want the UI and back-end web service to resemble fine grained RPC operations & be more closely coupled, compared to larger grained, heavier web services operations. So can we maybe use JSON or even binary to transfer objects and/or make calls?

    I am new to .NET 3 & 3.5 (and haven’t worked with .NET 2 for a while) so I don’t know what options are out there.

    Thanks!

    Jacques

  5. 5 timross May 9, 2008 at 8:54 am

    Hi Jacques, thanks for your comment. The Silverlight MVP implementation allows the presentation logic to be executed locally in the Silverlight application. This results in a more responsive user interface. The Silverlight app should only need to communicate with the server for data access and to process core business logic. Asynchronous calls to web services allows to user interface remain responsive when sending or retrieving data. WCF is the preferred service mechanism if the server application is build in .NET.

  6. 6 alkama May 12, 2008 at 5:29 pm

    hi, it is me again
    thanks for your post, i still trying to implment this MVP design pattenn & silverlight 2.
    I have a probleme with the accross domain. the ClientModel that call my web service throw a exception “Accross domain error”.

    I search on the web i find some example concerning crossdomain.xml & clientaccesspolicy.xml to allow across access but that not resulve the probleme.
    Can you help me if you now the solution!
    thanks

  7. 7 David P May 15, 2008 at 10:58 pm

    Please use Adventure Works sample DB (installs with SQL 2005). “Nobody” has Northwind anymore, that was for SQL 2000. This is a Silverlight app, so it assumes VS 2008 and SQL 2005.

    But anyway, this concept looks great. Hope to try it out once I get a workng DB (i cant find northwind). Thanks.

  8. 8 timross May 16, 2008 at 6:13 am

    Hi David, thanks for your comment. I used the Northwind database, simply because it is the traditional demo database. I have now included the Northwind script in the solution for those who don’t have it installed.

  9. 9 Oleg Zhukov July 24, 2008 at 9:35 am

    Hi Tim,

    I have developed a framework for simplifying using the MVP pattern in Silverlight applications: http://www.mvcsharp.org. It supports Winforms and ASP.NET UIs as well. You might be interested in it :)

    Kind regards,

    Oleg Zhukov

  10. 10 timross July 27, 2008 at 8:02 pm

    Hi Oleg, your MVC# framework looks great! I really like the navigation and task features and the fact it can work with multiple UI technologies. My only concern is the name – it took me some time to find out why it is called MVC#, rather than MVP#. But aside from that, great stuff!

  11. 11 Oleg Zhukov July 28, 2008 at 10:59 am

    Thank you Tim! Nice to hear that the confusing name is its largest drawback :)) I just wanted to emphasize that MVP is an enhanced, “sharp” variant of more popular MVC. So I came up with MVC# name :)

  12. 12 Ryan van der Kooy October 28, 2008 at 5:50 pm

    Thanks Tim! MVP for silverlight totally makes sense…i’ve been searching for a good pattern to follow when building my ui and this works great! quick question..where would you suggest form validation take place? should it be in the user control or in the presenter? Thanks in advance,-Ryan

  13. 13 timross October 28, 2008 at 9:04 pm

    Hi Ryan, thanks for your comment. I would suggest that validation rules be kept in the presenter. This way you can test the validation logic independently of the UI controls. However, you might want to provide a visual indicator next to the field that failed validation. In that case you will need the presenter to tell the view which field failed validation. I am not sure exactly how this would work, but I will investigate further and report back with any findings.

  14. 14 Ryan van der Kooy October 30, 2008 at 6:25 pm

    Tim,
    Would it make sense to have isValid (boolean) properties in the interface strickly for the purpose of testing and then also raise some NotValid events from the presenter? for example, part of a ICustomerView interface might look something like (in vb)

    Property PhoneNumber() As String
    Property PhoneNumberIsValid as Boolean

    this way you could check the PhoneNumberIsValid property in your test.

    But then as far as the actual UI is concerned, the constructor of the usercontrol could contain…

    AddHander _customerPresenter.PhoneNumberNotValid, AddressOf OnPhoneNumberNotValid

    and In the OnPhoneNumberNotValid event handler, you could make any necessary notifications to the user (set textbox background to red, etc.)

    Does that make sense?

    Thanks, -Ryan

  15. 15 leo January 22, 2009 at 12:42 am

    Hi Tim, very nice post, super useful, it will solve a lot of problems, thanks.

    do you know why this is happening? I even copied the file into the clientbin folder and nothing.

    System.InvalidOperationException: Cannot find ‘ServiceReferences.ClientConfig’ in the .xap application package. This file is used to configure client proxies for web services, and allows the application to locate the services it needs. Either include this file in the application package, or modify your code to use a client proxy constructor that specifies the service address and binding explicitly. Please see inner exception for details. —> System.Xml.XmlException: Cannot find file ‘ServiceReferences.ClientConfig’ in the application xap package.
    at System.Xml.XmlXapResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
    at System.Xml.XmlReaderSettings.CreateReader(String inputUri, XmlParserContext inputContext)

  16. 16 timross February 1, 2009 at 12:23 pm

    Hi Leo, thanks for your comment. Sorry for the late response, I don’t seem to be getting emails from wordpress any more when a comment is posted! Try removing and re-adding the service references to the web services. Also make sure you have the latest version of the Silverlight runtime. Also, I found this discussion which might be useful: http://silverlight.net/forums/t/18528.aspx

  17. 17 Tim C February 12, 2009 at 10:32 am

    Hi Tim

    I love your MVP pattern, and will be looking to use something similar in future development projects, but I have a few questions.

    What is your recommended exception handling model for this design pattern?

    if for instance; if updating a customer failed, and you wanted to inform the user, would you create a CustomerUpdateFailed event, or something similar?
    it seems that following that path may lead to a lot of events being needed.

    do you have any opinions on this.

    thanks

    Tim C

  18. 18 timross February 15, 2009 at 5:43 pm

    Hi Tim. Yes, raising an event would be one option for responding to an asynchronous update result. Another option would be to use an Event Aggregator to pass messages rather than raise events. I personally prefer this option, as components can receive messages without having a dependency on the publisher of the message. For more information on using an Event Aggregator, check out this article: http://kentb.blogspot.com/2008/03/event-hub.html

    Hope this helps!

  19. 19 Topolino March 3, 2009 at 2:09 pm

    Hello,

    i have tried your solution and when i execute it i have pb to consumme your webservice : error status 400 !!!

    I cannot give you a message error cause is in French ;o)

    Thanks for your recommandation

    regards

  20. 20 Don July 5, 2009 at 7:39 am

    The MVP pattern is great. I am currently re-writing my product’s administration section (http://clovercontent.com) using this pattern for several key reasons:

    1) As pointed out, testability. All of the code in a MVP application can be tested easily.

    2) I can write a MVP application and create both a Web UI using ASP.Net and a Silverlight UI using 3/4 of the same (tested) code. The only thing that has to be done differently is obviously the specific UI behavior.

    3) If my clients want it, I can write a desktop application using WPF in the future and use the same (tested) code.

  21. 21 Ed. September 5, 2009 at 2:13 pm

    Hi,

    Very good article. I’m trying to artchitect my Silverlight project the same way, but I’m running into issues with the domain/model. My domain classes when exposed via the web service reference naturally are different (for example, the properties on my domain classes are not part of the service classes). So, if I have a Customer domain class that’s returned from a web service call, what’s the best practice for mapping the web service version of Customer to my domain model customer for use by the client?

    Thank you for your time.
    – Ed.

  22. 22 timross September 5, 2009 at 4:03 pm

    Hi Ed, you can either do a manual mapping of properties from the web service proxy into your model, or you can use Automapper to do an automatic convention-based mapping of the properties. Either way, I would use a factory method that takes a proxy object and returns a model object, e.g. var customer = Customer.CreateFrom(wsCustomer).

  23. 23 Sasi November 18, 2009 at 3:12 am

    Hi Tim,

    Your source code was amazing !!. It helped me lot. Thanks a lot. but I want to clarify one thing that how to expose load event from view to presenter. I checked your code but not been implemented IView load event in page.xaml.cs so could you pls tell how to do it ?.

    Thanks,
    Sasi

  24. 24 Jon December 3, 2009 at 9:51 am

    Hi Tim,

    Your article is pretty good and clear. It’s just happened that I have an applicatoin / a framework running in WPF, ASP.NET using the MVP Pattern. Using the pattern I’ve achieved a centralised code for both platforms and decided to create it on a Silverlight 3.0 platform, this only means that I will be using the same IViews, Presenters and Model for the Silverlight, it’s just not possible to do this since my projects are not created in Silverlight platform, any ideas on how to do this?

    Thank you in advance.

  25. 25 Tim Ross December 6, 2009 at 10:07 am

    Hi Jon, Silverlight cannot reference standard .NET assemblies, so you will need a way of sharing your code between Silverlight and other .NET applications. This post may help: http://blogs.msdn.com/jimmytr/archive/2008/06/11/share-sourcecode-between-silverlight-and-wpf-applications.aspx

  26. 26 timross December 6, 2009 at 10:23 am

    Hi Sasi, thanks for your comment. The Page class that implements IView inherits from UserControl, which inherits from FrameworkElement that has the Loaded event. The presenter can access the Loaded event through the IView interface that gets passed to it. Hope that answers your question.


  1. 1 Silverlight 2.0 MVP Architecture « Robert’s Dot Net World Trackback on November 6, 2008 at 12:14 pm
  2. 2 Recent Links Tagged With "rhinomocks" - JabberTags Trackback on December 24, 2008 at 5:04 pm
  3. 3 Newly Noted #23 | Patrick Verbruggen's Blog Trackback on March 18, 2009 at 5:16 pm
Comments are currently closed.




Follow

Get every new post delivered to your Inbox.

%d bloggers like this: