In Part 1 of ViewModel and .NET RIA Services, which I recommend you check out first if you haven't, I created a simple product search UI using Silverlight and .NET RIA Services using the ViewModel (aka MVVM) pattern. One of benefits of the ViewModel pattern is that it creates a nice contract between the view and associated logic, i.e. a contract between the designer and the developer. Another key benefit of the ViewModel pattern is that it furthers testability - more of your presentation tier is now unit testable. This post touches on that second benefit.
In doing so, it will allow me to go into a couple of other related topics:
- First, this application uses .NET RIA Services. This post will demonstrate how you can mock out the server when using the client-side functionality of .NET RIA Services. This is important because it allows the view models to be tested independently outside of the end-to-end application, thereby minimizing dependencies.
- Second, once we factor out dependencies from within the view model, we need something like dependency injection to initialize view models. This post will also demonstrate the super-minimal and lightweight IoC container and dependency injection implementation in Silverlight.FX
.
Mocking the Server
On the server, I have defined a Catalog domain service using .NET RIA Services, which makes a Catalog object along with a list of Products available for my client side code, and specifically, the view model implementation to use. Here is a brief snippet of that view model code from last time:
public class SearchViewModel : Model {
private Catalog _catalog;
public SearchViewModel() {
_catalog = new Catalog();
}
public IEnumerable<Product> Products {
get {
return _catalog.Products;
}
}
public void Search(string keyword) {
...
_catalog.Products.Clear();
_catalog.LoadProducts(keyword);
}
}
As you can see, the view model simply instantiates a Catalog instance and starts using it. It doesn't have to worry about how the client-side Catalog object communicates with its server-side Catalog counterpart, URIs etc., thanks to the infrastructure provided by .NET RIA Services.
However, the architecture of the client-side bits does include a layering, where the client-side programming model (i.e. the Catalog, its list of Products, Load etc.) are layered on a proxy layer that encapsulates serialization and transport. The default proxy layer uses DataContract serialization and HTTP to communicate with the implicit service endpoints created on the server. If you look at the generated code you'll see the following:
public class Catalog : DomainContext {
public Catalog() : base(new HttpDomainClient(new Uri("..."))) {
}
}
Here is a diagram that shows the different pieces and how they are related:

The DomainClient interface is a generic proxy interface. It represents the ability to issue a query, process a change set, or invoke an operation. You can implement your own version of a DomainClient, and use that instead of the HTTP domain client. For example, you could write a DomainClient that knew how to speak to Twitter, and thereby expose the .NET RIA Services programming model over the Twitter API (idea for followup post). More specifically, in the context of this post, I can create a DomainClient that surfaces some local mock data and use that when constructing a mock Catalog that I use within my view model at unit test time.
The code associated with the blog post has a derived implementation called LocalDomainClient that simplifies writing such a mock when everything is local and asynchronous operation is not necessary. Specifically it implements all the async methods on DomainClient (Begin/EndQuery, Begin/EndSubmit, and Begin/EndInvoke ) and turns around and calls into synchronous methods that you get to override in your mock (Query, Submit and Invoke).
Here's the implementation of my mock DomainClient from within the Test project:
public class MockDomainClient : LocalDomainClient {
private IEnumerable<Entity> _mockEntities;
public MockDomainClient(IEnumerable<Entity> mockEntities) {
_mockEntities = mockEntities;
}
protected override IQueryable<Entity> Query(string queryName, IDictionary<string, object> parameters) {
// This can be as complex as you want it to be; alternatively you can create specific
// mocks for each unit test you have, thereby simplifying the implementation of Query.
return _mockEntities.AsQueryable();
}
}
When I want to use this mock, I simply need to use the overload of the Catalog constructor that takes in a DomainClient. For example:
DomainClient mockDomainClient = new MockDomainClient(...);
Catalog mockCatalog = new Catalog(mockDomainClient);
The APIs on this mock Catalog instance work just like a real Catalog, which is key. Essentially you can replace the underlying serialization and transport layer without changing the programming model that layers on top.
Factoring the ViewModel to use a Mock
Now that I have the ability to create and use a mock Catalog, I need my view model to do so at unit test time, while using the real Catalog at runtime. Recall from above, that currently my view model constructs an instance of Catalog in its constructor. Instead, I'd like it to take a Catalog instance in its constructor.
public class SearchViewModel : Model {
private Catalog _catalog;
public SearchViewModel(Catalog catalog) {
_catalog = catalog;
}
}
With this change, I can write the following unit test, using the Silverlight unit testing framework:
[TestClass]
public class SearchViewModelTests : SilverlightTest {
[TestMethod]
[Asynchronous]
public void TestEmptyKeywordIsIgnored() {
bool searchStarted = false;
// The setup...
List<Entity> mockEntities = new List<Entity>();
Catalog catalog = new Catalog(new MockDomainClient(mockEntities));
SearchViewModel viewModel = new SearchViewModel(catalog);
viewModel.SearchStarting += delegate(object o, EventArgs e) {
searchStarted = true;
};
// The test...
viewModel.Search(String.Empty);
EnqueueDelay(1000);
// The verification
EnqueueCallback(() => Assert.IsFalse(searchStarted, "Did not expect a search to start."));
EnqueueTestComplete();
}
}
Note that as you'd expect by now, the view model is passed in a mock Catalog, and hence I have no dependencies on any of my server code. In fact, I don't have any dependencies on a server either. So I can run the unit tests without deploying into a Web application. Simply load up the test HTML page created for a Silverlight application into the browser.
In similar fashion, I can write some more tests to test more of the behavior of my SearchViewModel, which you'll see when you open up the project and code associated with the blog post. Here is a screenshot of running the tests:
Dependencies and IoC
So at this point, we have our view model taking in a Catalog, the unit tests mocking the server using a mock DomainClient, and passing in a mock Catalog into the view model.
However, now at runtime we need to pass in a real Catalog using the default HttpDomainClient that does go back to the server to implement Query, Submit and Invoke. There are multiple ways to do this. One simple approach is to have the view model continue to instantiate a Catalog when one is not passed in. An alternative is to express this as a dependency and have an external IoC container satisfy this dependency. Depending on your tastes, and needs, this might be interesting, and I'll use this post as a context to introduce the IoC container and functionality provided by Silverlight.FX.
First, I'll declare Catalog as a dependency.
public class SearchViewModel : Model {
private Catalog _catalog;
public SearchViewModel([Dependency] Catalog catalog) {
_catalog = catalog;
}
}
As simple as that. Either constructor parameters or get/set properties can be marked as dependencies. Dependencies can be required (the default), or marked as optional.
Next, I'll go and initialize my container. By default, in Silverlight.FX, the Application is a global container. You can create your own containers at logical scopes, but for this, the global container will suffice. Furthermore, Application provides a XAML-friendly way to define a set of components to populate this global container. So, in XAML, I can define the following:
<fxapp:XApplication
xmlns:fxapp="clr-namespace:SilverlightFX.Applications;assembly=SilverlightFX"
...>
<fxapp:XApplication.Components>
<fxapp:ComponentFactory ComponentType="MyApp.DomainLogic.Catalog" />
</fxapp:XApplication.Components>
</fxapp:XApplication>
In this example, I want a new instance of Catalog to be created each time a dependency of type Catalog is to be fulfilled. Hence I am using . If I wanted a common Catalog instance to be shared, I could use the following XAML just as well:
<fxapp:XApplication.Components>
<app:Catalog />
</fxapp:XApplication.Components>
That's all I have to do. When the view model is created by the view, the framework code in Silverlight.FX, checks if there is an IoC container available, and there is one, since we've defined some components, it delegates creation of the view model to the container. The container attempts to create and initialize any object by fulfilling the dependencies of those objects by satisfying dependencies of that object.
Summary
So there you have it... to recap, one of the important benefit of using the view model pattern is increased testability. You can use .NET RIA Services and mock the server using the DomainClient extensibility point while testing your client-side view models. If you're using the view model pattern implementation as it exists in Silverlight.FX, you can also use the complementary lightweight IoC and dependency injection system.
Here is the code for the entire project, along with unit tests.
I did not touch on testability and unit testing the code in the Catalog domain service that runs on the server. That is certainly possible, and will visit that in the future. This post is scoped to the view model pattern and client-side half of the overall picture.