<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8944256652433533647</id><updated>2010-09-03T11:58:38.672-04:00</updated><title type='text'>C#er : IMage</title><subtitle type='html'>C# and .NET solutions: Silverlight, NHibernate, JavaScript, AJAX, Unity, and more.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default?orderby=updated'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default?start-index=26&amp;max-results=25&amp;orderby=updated'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>160</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-1887086505534757163</id><published>2010-09-01T15:42:00.000-04:00</published><updated>2010-09-01T15:42:55.669-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Managed Extensibility Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><title type='text'>Hello, MEF for Silverlight Quickstart</title><content type='html'>&lt;p&gt;Published another quickstart. This is an introductory quickstart for the Managed Extensibility Framework, and is similar to the previous one except that it is specific to Silverlight. You can take a look at the article and watch the short video by &lt;a href="http://mefcontrib.com/hello,-mef-silverlight.aspx" target="_blank"&gt;clicking here&lt;/a&gt;.&lt;br /&gt;
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-1887086505534757163?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://mefcontrib.com/hello,-mef-silverlight.aspx' title='Hello, MEF for Silverlight Quickstart'/><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/1887086505534757163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/09/hello-mef-for-silverlight-quickstart.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/1887086505534757163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/1887086505534757163'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/09/hello-mef-for-silverlight-quickstart.html' title='Hello, MEF for Silverlight Quickstart'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-396608773085743086</id><published>2010-08-27T21:30:00.000-04:00</published><updated>2010-08-27T21:39:19.073-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvvm'/><category scheme='http://www.blogger.com/atom/ns#' term='prism'/><category scheme='http://www.blogger.com/atom/ns#' term='validation'/><title type='text'>Fluent Validation with MEF and PRISM</title><content type='html'>&lt;p&gt;Validation is a topic that comes up quite frequently. One concern is how to honor DRY (don't repeat yourself) principles and create a framework that is reusable across layers. There are some very robust and tested frameworks out there, but sometimes they might be more than what you are looking for. In this post, I'll show you how to build a standalone validation library that can be shared between Silverlight and the server, then integrated via MEF and PRISM for fluent validation.&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Rules and Violations&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;First things first. We need to lay down the validation framework. One technique I've learned when working with Silverlight is to build your main classes as Silverlight classes first, so they take advantage of the "lower denominator." Class libraries built in Silverlight are then easily shared on the server - the easiest, "out of the box" way is to create a mirrored .NET project and link the classes.&lt;br /&gt;
&lt;p&gt;I suspect when a rule is violated, it might pertain to more than one property, so I created a rule violation to look like this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public class RuleViolation 
{
    public RuleViolation(string message, IEnumerable&amp;lt;string&gt; properties)
    {
        Message = message;
        Properties = properties;
    }

    public string Message { get; private set; }

    public IEnumerable&amp;lt;string&gt; Properties { get; private set; }
}
&lt;/pre&gt;&lt;p&gt;Next, we need to define what a validation rule looks like. What I want to do is define various rules and tag them with MEF to export, and have a centralized place to request and execute the rules. The interface I decided to go with looks like this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public interface IValidationRule
{
    IEnumerable&amp;lt;RuleViolation&gt; Validate(string propertyName, object propertyValue);

    IEnumerable&amp;lt;RuleViolation&gt; Validate(string propertyName, object propertyValue, Dictionary&amp;lt;string,object&gt; parameters);        
}
&lt;/pre&gt;&lt;p&gt;We can simply pass a property and a value, possibly with additional parameters, and receive a list of violations. The parameters dictionary is one place some might complain. Instead of having fine-grained validations that each have different signatures, I like to compromise and use an open interface. I can still type it somewhat (I'll show you how) but I prefer the flexibility of requesting the common interface over keeping track of all of the various method signatures.&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Defining Rules&lt;/b&gt;&lt;/p&gt;&lt;p&gt;To explain what I mean, let's build two validation rules, one that takes parameters, and one that doesn't. Here is a rule that says, "this is required." First, we'll create a base validation class to take care of common tasks so our actual rules are easier to implement:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public abstract class BaseRule : IValidationRule
{
    private readonly List&amp;lt;RuleViolation&gt; _violations = new List&amp;lt;RuleViolation&gt;();

    protected void AddViolation(string message, string property)
    {
        AddViolation(message, new[] { property });
    }

    protected void AddViolation(string message, IEnumerable&amp;lt;string&gt; property)
    {
        var violation = new RuleViolation(message, property);
        _violations.Add(violation);
    }

    protected abstract void _Validate(string propertyName, object propertyValue, Dictionary&amp;lt;string,object&gt; parameters);

    public IEnumerable&amp;lt;RuleViolation&gt; Validate(string propertyName, object propertyValue)
    {
        return Validate(propertyName, propertyValue, null);
    }

    public IEnumerable&amp;lt;RuleViolation&gt; Validate(string propertyName, object propertyValue, Dictionary&amp;lt;string, object&gt; parameters)
    {
        _violations.Clear();
        _Validate(propertyName, propertyValue, parameters);
        return new List&amp;lt;RuleViolation&gt;(_violations);
    }
}
&lt;/pre&gt;&lt;p&gt;Let's get one assumption out the way. This code is not thread-safe. You'll notice I'm using state on the class to handle the validation, by clearing the collection, then calling the derived class, and finally returning the result. If two threads entered this class, there would be an issue.&lt;br /&gt;
&lt;p&gt;You might want to add the extra plumbing to make it thread safe, and that's fine by me. I personally am not planning to execute anywhere other than within my view model getters and setters. I'm only validating as the result of user input (except in my testing, of course, where I can control this by creating new instances) which is via databinding. That means that if I code this correctly, any validations will actually only come in one thread: the main UI thread.&lt;br /&gt;
&lt;p&gt;Here's what a required value looks like:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public class ValueIsRequired : BaseRule 
{
    protected override void _Validate(string propertyName, object propertyValue, Dictionary&amp;lt;string,object&gt; dictionary)
    {
        if (propertyValue == null || string.IsNullOrEmpty(propertyValue.ToString()))
        {
            AddViolation("Value is required.", propertyName);
        }
    }
}
&lt;/pre&gt;&lt;p&gt;Notice that I'm ignoring the dictionary. When checking to see if only alpha characters are in a string (such as a title, for example) I might want to make it optional whether or not to allow spaces in between characters. Here's a rule that takes in an optional parameter:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public class ValueOnlyContainsAlpha : BaseRule 
{
    private const string PATTERN = @"[^a-zA-Z]";
    private const string PATTERNWITHSPACE = @"[^a-zA-Z ]";
        
    public const string ALLOW_SPACE = "AllowSpace";

    protected override void _Validate(string propertyName, object propertyValue, Dictionary&amp;lt;string,object&gt; dictionary)
    {
        if (propertyValue is string &amp;&amp; Regex.IsMatch(propertyValue.ToString().Trim(), 
            dictionary.GetParameter&amp;lt;bool&gt;(ALLOW_SPACE) ? PATTERNWITHSPACE : PATTERN))
        {
            AddViolation("Value must be alpha only.", propertyName);                
        }
    }
}
&lt;/pre&gt;&lt;p&gt;(We could extend that a little more and have a separate message to define spaces or not ... this is just here to illustrate the point.) If you're wondering about the &lt;code&gt;GetParameter&lt;/code&gt; method, I extended the dictionary like this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public static T GetParameter&amp;lt;T&gt;(this Dictionary&amp;lt;string, object&gt; dictionary, string parameterName)
{
    return dictionary == null
                ? default(T)
                : dictionary.ContainsKey(parameterName) ? (T) dictionary[parameterName] : default(T);
}
&lt;/pre&gt;&lt;p&gt;This is just a convenience to cast the value or get the default if it is not in the dictionary.&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Exporting Rules&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;The idea with rules is that it should be easy to export them to the system so a centralized location can pass them out. In this case, I can bind validations later in the game but whatever is using the validations must be aware of the type of the rule. To me, that makes perfect sense - a range validation doesn't make sense unless I know there is a range validation rule. &lt;br /&gt;
&lt;p&gt;Let's create an export attribute and some metadata for the rule, and we'll just export them by type:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class,AllowMultiple = false)]
public class ExportRuleAttribute : ExportAttribute
{
    public ExportRuleAttribute(Type ruleType) : base(typeof(IValidationRule))
    {
        Rule = ruleType;
    }

    public Type Rule { get; set; }
}

public interface IExportRuleMetadata
{
    Type Rule { get; }
}
&lt;/pre&gt;&lt;p&gt;Now I can export my rules like this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;[ExportRule(typeof(ValueIsRequired))]
public class ValueIsRequired : BaseRule 
&lt;/pre&gt;&lt;p&gt;We need to "catch" the rules somewhere. I'll create a signature that mirrors the validation signature, with a factory:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public interface IValidationFactory
{
    IEnumerable&amp;LT;RuleViolation&gt; ValidateThat&amp;lt;T&gt;(string propertyName, object propertyValue) where T : IValidationRule;

    IEnumerable&amp;lt;RuleViolation&gt; ValidateThat&amp;lt;T&gt;(string propertyName, object propertyValue, Dictionary&amp;lt;string,object&gt; parameters) where T : IValidationRule;
}
&lt;/pre&gt;&lt;p&gt;Here is where the fluent interface starts to creep in. Notice these are not just method names, but names that are starting to make a statement ("validate that ..."). Let's implement this with MEF:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;[Export(typeof(IValidationFactory))]
public class ValidationFactory : IValidationFactory
{
    [ImportMany(AllowRecomposition = true)]
    public Lazy&amp;lt;IValidationRule,IExportRuleMetadata&gt;[] Rules { get; set; }

    private IValidationRule GetRule&amp;lt;T&gt;() where T: IValidationRule
    {
        return (from rules in Rules
                where rules.Metadata.Rule.Equals(typeof (T))
                select rules.Value).FirstOrDefault();
    }

    public IEnumerable&amp;lt;RuleViolation&gt; ValidateThat&amp;lt;T&gt;(string propertyName, object propertyValue) where T : IValidationRule
    {
        return GetRule&amp;lt;T&gt;().Validate(propertyName, propertyValue);
    }

    public IEnumerable&amp;lt;RuleViolation&gt; ValidateThat&amp;lt;T&gt;(string propertyName, object propertyValue, Dictionary&amp;lt;string, object&gt; parameters) where T : IValidationRule
    {
        return GetRule&amp;lt;T&gt;().Validate(propertyName, propertyValue, parameters);
    }
}
&lt;/pre&gt;&lt;p&gt;We capture all of the rules. When the client requests to "validate that..." we'll fetch the type and pass through the parameters. &lt;br /&gt;
&lt;p&gt;&lt;b&gt;Fluent Interface&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Before I hook this in, I want to add a few extension methods to make the interface more fluent. Remember how I mentioned I'm using a dictionary for additional parameters, but I can type it somewhat? You saw the example in the alpha with the optional spaces. I can send in a parameter that is "true" for allowing spaces. Let's make it easier to pass that parameter, so our interface can look like this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;Validator.ValidateThat&amp;lt;ValueOnlyContainsAlpha&gt;(propertyName,value,ValueOnlyContainsAlpha.ALLOW_SPACE.AsParameterWithValue(true));
&lt;/pre&gt;&lt;p&gt;That makes it a little easier to read without making a dictionary, adding the values, etc. In fact, we'll also want to extend this (for example, if we need a minimum and maximum range) so I'll also add an extension for additional parameters. The goal is to do this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;Validator.ValidateThat&amp;lt;ValueIsInRange&gt;(propertyName
   ,value
   ,ValueIsInRange.MIN.AsParameterWithValue(1)
    .WithParameter(ValueIsInRange.MAX,10));
&lt;/pre&gt;&lt;p&gt;Here's what the extension methods look like:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public static Dictionary&amp;lt;string, object&gt; AsParameterWithValue(this string parameterName, object parameterValue)
{
    return new Dictionary&amp;lt;string, object&gt; {{parameterName, parameterValue}};
}

public static Dictionary&amp;lt;string, object&gt; WithParameter(this Dictionary&amp;lt;string, object&gt; dictionary, string parameterName, object parameterValue)
{
    dictionary.Add(parameterName, parameterValue);
    return dictionary;
}
&lt;/pre&gt;&lt;p&gt;The last extension I want to create for our fluent interface is to allow chaining of validations. In most situations, you'll have more than one validation. Because validations return an enumeration of violations, it is easy enough to combine them by merging their results. Here's what the goal is:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;var violations = Validator.ValidateThat&amp;lt;ValueIsRequired&gt;(propertyName,value)
.AndAlso(()=&gt;Validator.ValidateThat&amp;lt;ValueOnlyContainsAlpha&gt;(propertyName
   ,value
   ,ValueOnlyContainsAlpha.ALLOW_SPACE.AsParameterWithValue(true)));
&lt;/pre&gt;&lt;p&gt;We accomplish the merge like this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public static IEnumerable&amp;lt;RuleViolation&gt; AndAlso(this IEnumerable&amp;lt;RuleViolation&gt; source, Func&amp;lt;IEnumerable&amp;lt;RuleViolation&gt;&gt; target)
{
    var list = new List&amp;lt;RuleViolation&gt;(source);
    list.AddRange(target());
    return list;
}
&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Using PRISM to Host the Validations&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;Now the validation project can easily be shared/linked to .NET and used for server-side validation. We're more concerned with the immediate UI feedback. How does this engine integrate with Model-View-ViewModel?&lt;br /&gt;
&lt;p&gt;PRISM provides MVVM guidance in their preview 4. Download it &lt;a href="http://compositewpf.codeplex.com/" target="_blank"&gt;here&lt;/a&gt;. There is a base MVVM class in the MVVM quickstart that implements helpers for notify property changed events as well as &lt;code&gt;IDataErrorInfo&lt;/code&gt;, a standard means for identifying validation errors. John Papa discusses this interface &lt;a href="http://johnpapa.net/silverlight/enabling-validation-in-silverlight-4-with-idataerrorinfo/" target="_blank"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;p&gt;What we want to do is hook into the supplied class and make it easy to validate. The reference implementation already has methods for setting and clearing errors against properties, so we just want to provide a validation "front-end" to hook into this feature.&lt;br /&gt;
&lt;p&gt;First, we'll expose our validation factory by importing it into the base view model class:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;[Import]
public IValidationFactory Validator { get; set; }
&lt;/pre&gt;&lt;p&gt;Next, we'll supply a method that derived view models can use to hook into validations:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;protected virtual void WithValidationFor&amp;lt;T&gt;(Expression&amp;lt;Func&amp;lt;T&gt;&gt; propertyExpression, IEnumerable&amp;lt;RuleViolation&gt; violations)
{
    var propertyName = ExtractPropertyName(propertyExpression);

    var hasViolations = false;

    foreach(var violation in violations)
    {
        hasViolations = true;
        SetError(propertyName, violation.Message);
    }

    if (!hasViolations)
    {
        ClearErrors(propertyName);
    }
}
&lt;/pre&gt;&lt;p&gt;Very simple - we simply parse the validations, and if any exist, we set them on the property, otherwise we reset them. &lt;br /&gt;
&lt;p&gt;&lt;b&gt;Putting it All Together&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;I'm not supplying full source on purpose - obviously not everyone will use the PRISM reference implementation for a solution and may have another framework they'd prefer to use, and the intent here is educational. In this example, I can validate that a name is required and must be alpha only (with spaces) like this on a view model derived from the base:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;private string _name;

public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        RaisePropertyChanged(() =&gt; Name);
        var propertyName = ExtractPropertyName(() =&gt; Name);
        WithValidationFor(()=&gt;Name,
            Validator.ValidateThat&amp;lt;ValueIsRequired&gt;(propertyName,value)
            .AndAlso(
            ()=&gt;Validator.ValidateThat&amp;lt;ValueOnlyContainsAlpha&gt;(propertyName,value,ValueOnlyContainsAlpha.ALLOW_SPACE.AsParameterWithValue(true))));
    }
}
&lt;/pre&gt;&lt;p&gt;And there you have it: a (somewhat) fluent interface for validation that sits on top of PRISM's MVVM quickstart guidance.&lt;br /&gt;
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-396608773085743086?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/396608773085743086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/fluent-validation-with-mef-and-prism.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/396608773085743086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/396608773085743086'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/fluent-validation-with-mef-and-prism.html' title='Fluent Validation with MEF and PRISM'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-8465313981834783083</id><published>2010-08-22T11:40:00.001-04:00</published><updated>2010-08-22T11:43:08.568-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Managed Extensibility Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='reactive extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='coroutine'/><category scheme='http://www.blogger.com/atom/ns#' term='asynchronous'/><title type='text'>Coroutines for Asynchronous Sequential Workflows using Reactive Extensions (Rx)</title><content type='html'>&lt;p&gt;I've been doing quite a bit with &lt;a href="http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx" target="_blank"&gt;Reactive Extensions (Rx)&lt;/a&gt; for Silverlight lately. One idea that I keep exploring is the concept of creative intuitive sequential workflows for asynchronous operations. You can read about my explorations using Wintellect's own &lt;a href="http://www.wintellect.com/PowerThreading.aspx" target="_blank"&gt;Power Threading Library&lt;/a&gt; in &lt;a href="http://csharperimage.jeremylikness.com/2010/03/sequential-asynchronous-workflows-in.html" target="_blank"&gt;this post&lt;/a&gt; along with a simple solution using an interface and enumerators in &lt;a href="http://csharperimage.jeremylikness.com/2010/03/sequential-asynchronous-workflows-part.html" target="_blank"&gt;part 2&lt;/a&gt; of that series. I'm tackling the problem from a different angle.&lt;br /&gt;
&lt;p&gt;First, my disclaimers: this is more of an exploratory, "Here's what can be done" post. Please don't take this as best practice or guidance, but more of another way of looking at the solution as well as an opportunity to dive deeper into Reactive Extensions. Also understand I am by no means an expert with Rx so I welcome feedback related to this experiment.&lt;br /&gt;
&lt;p&gt;The concept is straightforward: there are often times we want an asynchronous set of operations to perform sequentially. Perhaps you must load a list from a service, then load the selected item, then trigger an animation. This can be done either by chaining the completed events or nesting lambda expressions, but is there a cleaner way?&lt;br /&gt;
&lt;p&gt;To me, a cleaner solution would make it easy to see what happens sequentially, and also easy to fire the sequence. If it becomes too complex to force the sequential workflow, it buys us nothing from the traditional methods of wiring into completed events or nesting lambda expressions.&lt;br /&gt;
&lt;p&gt;So, I started with the idea of having a helper object that I could feed operations to in sequence, then fire it off. What would that look like? &lt;br /&gt;
&lt;p&gt;First, I made an interface to keep track of operations as they run and complete. This is by no means a perfect design but for now it's a sort of "recrusive container" for work done. The interface looks like this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public interface ISequentialResult 
{
    List&amp;lt;ISequentialResult&gt; Results { get; set; }
    object Value { get; set; }        
}
&lt;/pre&gt;&lt;p&gt;The result is simple: it aggregates all previous results, and contains a pointer to whatever is processing the current action in the sequence. Simple enough. Now on to a base class:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public abstract class BaseResult&amp;lt;T&gt; : ISequentialResult 
{
    protected IObserver&amp;lt;ISequentialResult&gt; Observer { get; set; }

    protected BaseResult(IObserver&amp;lt;ISequentialResult&gt; observer)
    {
        Results = new List&amp;lt;ISequentialResult&gt;();
        Observer = observer;
    }

    public List&amp;lt;ISequentialResult&gt; Results { get; set;}

    public object Value { get; set; }       

    public T TypedValue
    {
        get { return (T) Value; }
        set { Value = value; }
    }
}
&lt;/pre&gt;&lt;p&gt;The base class does a little more for us. First, it introduces the concept of an &lt;code&gt;IObserver&lt;/code&gt;. The observer is simply a class that receives notifications, and the type is the type of the notification. In this case, we allow for a derived type that will create the observer as well as take our "object" value and type it to a specific value. You'll see how the observer works with our sequences in a bit.&lt;br /&gt;
&lt;p&gt;Next, I created three implementations. One is just a default that does nothing, and the other two handle &lt;code&gt;Click&lt;/code&gt; events and &lt;code&gt;Storyboard&lt;/code&gt; interactions. Let's take a look at the handler for storyboards:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public class StoryboardResult : BaseResult&amp;lt;Storyboard&gt;  
{
    public StoryboardResult(IObserver&amp;lt;ISequentialResult&gt; observer, Storyboard sb) : base(observer)
    {
        TypedValue = sb;
        sb.Completed += SbCompleted;
        sb.Begin();
    }

    void SbCompleted(object sender, EventArgs e)
    {
        TypedValue.Completed -= SbCompleted;
        Observer.OnNext(this);
        Observer.OnCompleted();
    }       
}
&lt;/pre&gt;&lt;p&gt;You'll notice a few interesting things. We take in the story board, wire into its &lt;code&gt;Completed&lt;/code&gt; event, then fire it off (we could have changed the interface to have an &lt;code&gt;Execute&lt;/code&gt; method to give this more flexibility). The story board completion is the important piece to consider. First, the event is unhooked. Then, we pass the result to the observer. The observer is waiting for &lt;code&gt;ISequentialResult&lt;/code&gt; notifications. We provide it with one, but only after the story board is completed. We also tell the observer "we're done" (an observer can listen for multiple push notifications, so we could have created a handler that never completed, or one that aggregated multiple storyboards and only completed when all story boards were done). &lt;br /&gt;
&lt;p&gt;With that in mind, take a look at the &lt;code&gt;Click&lt;/code&gt; handler:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public class ClickResult : BaseResult&amp;lt;ButtonBase&gt;
{
    public ClickResult(IObserver&amp;lt;ISequentialResult&gt; observer, ButtonBase button) : base(observer)
    {
        TypedValue = button;
        button.Click += ButtonClick;
    }

    void ButtonClick(object sender, System.Windows.RoutedEventArgs e)
    {
        TypedValue.Click -= ButtonClick;
        Observer.OnNext(this);
        Observer.OnCompleted();                 
    }
}
&lt;/pre&gt;&lt;p&gt;This is very similar to the storyboard. There is nothing to "kick off" but instead this result simply registers itself whenever the target is clicked. Why would we do that? I'll get to the example in a minute.&lt;br /&gt;
&lt;p&gt;The most interesting part of workflow is the sequencer itself. This is the class that will manage the asychronous events and coordinate them. The key is that while they run sequentially, they also run asynchronously so there is no blocking. &lt;br /&gt;
&lt;p&gt;Here is the sequencer class:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public class Sequencer : IDisposable 
{
    private IDisposable _sequence;
    private ISequentialResult _result;

    private readonly List&amp;lt;Func&amp;lt;IObserver&amp;lt;ISequentialResult&gt;,ISequentialResult,ISequentialResult&gt;&gt; _sequences
        = new List&amp;lt;Func&amp;lt;IObserver&amp;lt;ISequentialResult&gt;, ISequentialResult,ISequentialResult&gt;&gt;();

    public void AddSequence(Func&amp;lt;IObserver&amp;lt;ISequentialResult&gt;, ISequentialResult,ISequentialResult&gt; sequence)
    {
        _sequences.Add(sequence);
    }
        
    public void Run(Action&amp;lt;Exception&gt; exception, Action&amp;lt;ISequentialResult&gt; completed)
    {
        _sequence = Observable.Iterate(_Sequencer)
            .Subscribe(
                next =&gt; { },
                exception,
                ()=&gt;completed(_result));
    }

    private IEnumerable&amp;lt;IObservable&amp;lt;Object&gt;&gt; _Sequencer()
    {
        var x = 0;

        _result = new DefaultResult(null) {Value = this};

        while (x &lt; _sequences.Count)
        {
            var sequence = _sequences[x];
            var step = Observable.Create&amp;lt;ISequentialResult&gt;(
                observer =&gt;
                    {
                        var newResult = sequence(observer, _result);
                        newResult.Results.Add(_result);
                        newResult.Results.AddRange(_result.Results);
                        _result = newResult;
                        return () =&gt; { };
                    }
                ).Start();

            yield return step;                

            x++;
        }

        _result.Results.Add(_result);
    }

    public void Dispose()
    {
        _sequence.Dispose();
    }
}
&lt;/pre&gt;&lt;p&gt;There's a lot going on here, so let's break it down.&lt;br /&gt;
&lt;p&gt;First, you'll notice two references: one to a disposable object, and one to a result. More on those in a bit.&lt;br /&gt;
&lt;p&gt;The list may seem confusing at first, but it's only because of all of the type specifiers. Each "step" is represented by a function. The sequence will call the function with an observer and the previous result, and expect to get a new result back. Think of it as "here's who is watching, and what happened the last time ... now give me what you have." &lt;br /&gt;
&lt;p&gt;A method is provided to add these steps to the sequence. &lt;br /&gt;
&lt;p&gt;The run method is interesting. This is where we set up our disposable reference because we're creating a long-running observer that we want to dispose of when the sequence itself is disposed. The iterate function takes a list of observable sequences and observes them sequentially. We provide an enumerator that feeds the observable sequences, and for each sequence in the "outer loop" (the main algorithm that drives the sequential work flow) we simply drive through the collection. If an exception is encountered, we'll call back with the exception. When completed, we call back with the final result.&lt;br /&gt;
&lt;p&gt;To better understand what's going on, take a look at the enumerator. For each iteration, we create a new observable stream. We call the function I mentioned earlier and pass the observer in. When we receive the result, we stack it recursively and store it, then iterate to the next in line. The &lt;code&gt;yield&lt;/code&gt; statement ensures the sequential operation completes (when we call the &lt;code&gt;OnCompleted&lt;/code&gt; in our result) before the next step begins.&lt;br /&gt;
&lt;p&gt;That's the complicated part: setting up the core framework. Now comes the easy part: plugging into it. &lt;br /&gt;
&lt;p&gt;In the XAML I placed a large red rectangle. There are three storyboards tied to the rectangle. One changes the colors, one shrinks it, and one twists it using the plane projection. There are also three buttons. One button kicks off the story boards. One button kicks off a sequential workflow that will run the story boards in order. The final button resets the story boards by calling &lt;code&gt;Stop&lt;/code&gt; on them. &lt;br /&gt;
&lt;p&gt;Let's have some fun. First, kicking off the story boards is simple enough:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;private void Button_Click(object sender, RoutedEventArgs e)
{
    StoryTwist.Begin();
    StoryShrink.Begin();
    StoryColor.Begin();
}
&lt;/pre&gt;&lt;p&gt;The reset button is also easy:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;private void Button_Click_2(object sender, RoutedEventArgs e)
{
    StoryTwist.Stop();
    StoryShrink.Stop();
    StoryColor.Stop();
}
&lt;/pre&gt;&lt;p&gt;Now for the sequential storyboards. This is where things should get easier for us. Instead of having to wire in several completed events or nesting lambdas, let's see what it looks like to run them in order using our sequencer:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;private void Button_Click_1(object sender, RoutedEventArgs e)
{
    if (_sequence != null)
    {
        _sequence.Dispose();
    }

    _sequence = new Sequencer();
    _sequence.AddSequence((o, r) =&gt; new StoryboardResult(o, StoryColor));
    _sequence.AddSequence((o, r) =&gt; new StoryboardResult(o, StoryShrink));
    _sequence.AddSequence((o, r) =&gt; new StoryboardResult(o, StoryTwist));
    _sequence.Run(ex =&gt; MessageBox.Show(ex.Message),
                    result =&gt;
                        {
                            foreach (var storyboard in
                                result.Results.Select(sequence =&gt; sequence.Value).OfType&amp;lt;Storyboard&gt;())
                            {
                                storyboard.Stop();
                            }
                            _sequence.Dispose();
                            _sequence = null;
                        });
}       
&lt;/pre&gt;&lt;p&gt;So what's going on? If we have a previous sequence running, we dispose it so we can start fresh. Then, we simply add each story board in the order we want it to fire (the observer is provided to us by the sequencer). Finally, we run it. If there is an error, show it. When the sequence is done, we iterate the results and find any result that was a story board and call the "stop" method. This means after the sequence completes, it will automatically restore the rectangle to its original state.&lt;br /&gt;
&lt;p&gt;Finally, to show just how powerful it is to drive sequential workflows &lt;i&gt;without blocking&lt;/i&gt;, I added one more method:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;private void _WaitForThreeClicks()
{
    _buttonSequence = new Sequencer();
    _buttonSequence.AddSequence((o, r) =&gt; new ClickResult(o, ResetButton));
    _buttonSequence.AddSequence((o, r) =&gt; new ClickResult(o, ResetButton));
    _buttonSequence.AddSequence((o, r) =&gt; new ClickResult(o, ResetButton));
    _buttonSequence.Run(ex=&gt;MessageBox.Show(ex.Message),
        result=&gt;
            {
                MessageBox.Show("You clicked the Reset button 3 times!");
                _buttonSequence.Dispose();
                _WaitForThreeClicks();
            });
}
&lt;/pre&gt;&lt;p&gt;This is a fun method. It literally creates three sequences, all "waiting" for the reset button to be clicked. After the sequence completes, we show a message indicating that 3 clicks happened, then restart the sequence recursively. I'll call it the first time just after &lt;code&gt;IinitializeComponent&lt;/code&gt;:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public MainPage()
{
    InitializeComponent();  
    _WaitForThreeClicks();
}      
&lt;/pre&gt;&lt;p&gt;There you have it! When you run the code, you'll get this:&lt;br /&gt;
&lt;p&gt;&lt;iframe width="450" height="450" border="0" src="http://apps.jeremylikness.com/samples/reactive-coroutines/ReactiveCoroutineTestPage.html"&gt;&lt;a href="http://apps.jeremylikness.com/samples/reactive-coroutines/ReactiveCoroutineTestPage.html" target="_blank"&gt;Click here to see the application in a new window&lt;/a&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;p&gt;Notice that you can keep clicking the sequence to start it over: there is no blocking. And whatever order you decide to click on other buttons, the reset button always faithfully shows a "3 click" message on the third click. &lt;br /&gt;
&lt;p&gt;You can download the full source code for this solution &lt;a href="http://www.wintellect.com/CS/files/folders/sample_files/entry18162.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-8465313981834783083?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/8465313981834783083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/coroutines-for-asynchronous-sequential.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/8465313981834783083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/8465313981834783083'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/coroutines-for-asynchronous-sequential.html' title='Coroutines for Asynchronous Sequential Workflows using Reactive Extensions (Rx)'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-3149516175558268919</id><published>2010-08-19T14:00:00.000-04:00</published><updated>2010-08-19T14:10:03.616-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Managed Extensibility Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='rx'/><category scheme='http://www.blogger.com/atom/ns#' term='reactive extensions'/><title type='text'>Simplifying Silverlight Web Service Calls with Reactive Extensions (Rx)</title><content type='html'>&lt;p&gt;I've been working with the Reactive Extensions (Rx) library quite a bit lately and am very impressed. While it is a new way of thinking about services, it certainly makes life much easier. In this example, I'll show you a way to simplify your web service calls using Rx. In fact, even if you &lt;i&gt;don't&lt;/i&gt; use Reactive Extensions, you may benefit from the proxy wrappers that I'll describe.&lt;br /&gt;
&lt;p&gt;I'm assuming you are familiar with Silverlight, web services, and have some exposure to the Managed Extensibility Framework. You'll also want to make sure you've got the latest version of &lt;a href="http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx" target="_blank"&gt;Rx for Silverlight 4&lt;/a&gt;.&lt;br /&gt;
&lt;p&gt;Let's get started! First, create a new Silverlight 4 Application. Keep all of the defaults: we &lt;i&gt;do&lt;/i&gt; want a web project, but we &lt;i&gt;aren't&lt;/i&gt; using RIA. &lt;br /&gt;
&lt;p&gt;&lt;b&gt;The Service: Server Side&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Let's create a simple calculator service. Sure, it is a simple example, but it will make it easier to focus on the details of Rx rather than puzzling over a more complex web service example. &lt;br /&gt;
&lt;p&gt;Create a new service and call it "Calculator." Just place it in the root of the web application. Create a contract and implement it, so that your service ends up looking like this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;namespace RxWebServices.Web
{
    [ServiceContract(Namespace = "http://csharperimage/")]
    public interface ICalculator
    {
        [OperationContract]
        long Add(int operand1, int operand2);       
    }

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Calculator : ICalculator
    {
        readonly Random _random = new Random();

        public long Add(int operand1, int operand2)
        {
            Thread.Sleep(TimeSpan.FromMilliseconds(_random.Next(1000) + 50));
            return operand1 + operand2;
        }        
    }
}
&lt;/pre&gt;&lt;p&gt;Notice I built in a delay. This is important to see how Rx helps us handle the asynchronous nature of web service calls. &lt;br /&gt;
&lt;p&gt;Go ahead and hit CTRL+F5 to build and run without debugging. This will set up the service end point for us to grab in Silverlight. Now, in your Silverlight project, let's set some things up.&lt;br /&gt;
&lt;p&gt;&lt;b&gt;The Service: Client Side&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;First, we want to add some references to both Reactive Extensions (Rx) and the Managed Extensibility Framework. Below, I've highlighted the references to add:&lt;br /&gt;
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=331&amp;g2_serialNumber=1"/&gt;&lt;br /&gt;
&lt;p&gt;Now we can add our service reference. Right-click references, choose "Add Service" and select "Discover Services in Solution". You should be able to select the calculator service. Put it in the namespace "Calculator Service" as depicted below.&lt;br /&gt;
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=334&amp;g2_serialNumber=2"/&gt;&lt;br /&gt;
&lt;p&gt;&lt;i&gt;Making Things Easy: ServiceProxy&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Services can seem complex, but with the factory patterns provided by the framework and the support of relative paths, abstracting the creation of an end point is easy. I like to create a proxy class thas manages the end points for me. In this example, I store the end point as a constant. However, you can easily make it a parameter for your Silverlight application and construct it on the fly. All my "consumer" really cares about is the service contract, not the details of how to wire in the service endpoint. So, let's make it easy. Take a look at the following class. The class itself is never instanced directly, but it will export the service contract so that wherever I import it, I'll have a fully wired version of the proxy ready to use.&lt;br /&gt;
&lt;p&gt;Create a folder called "Implementation" and add "ServiceProxy.cs". Your class will look like this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;namespace RxWebServices.Implementation
{
    public  class ServiceProxy
    {
        private const string CALCULATOR_SERVICE = "../Calculator.svc";
        private const string NOT_SUPPORTED = "Type {0} not supported";                

        private static readonly Dictionary&amp;lt;Type, Uri&gt; _serviceMap
            = new Dictionary&amp;lt;Type, Uri&gt; {{typeof (ICalculator), new Uri(CALCULATOR_SERVICE,UriKind.Relative)}};

        public static T GetProxyFor&amp;lt;T&gt;()
        {
            if (!_serviceMap.ContainsKey(typeof(T)))
            {
                throw new TypeLoadException(string.Format(NOT_SUPPORTED, typeof (T).FullName));
            }

            return
                new ChannelFactory&amp;lt;T&gt;(new BasicHttpBinding(), new EndpointAddress(_serviceMap[typeof (T)])).
                    CreateChannel();
        }

        [Export]
        public ICalculator CalculatorService
        {
            get { return GetProxyFor&amp;lt;ICalculator&gt;(); }
        }
    }
}
&lt;/pre&gt;&lt;p&gt;Take a look. We are mapping the service contract to the end points. In our case, it is relative to the site serving the Silverlight application. Because the application is in &lt;code&gt;ClientBin&lt;/code&gt;, we back up one level to access the service. Note this will work just as easily for a service hosted somewhere else: I would simply specify a relative or absolute uri. We only have one service, but the dictionary makes it easy to map multiple ones. The export uses the channel factory to generate an instance and return the client.&lt;br /&gt;
&lt;p&gt;&lt;i&gt;Our Internal Contract&lt;/i&gt;&lt;/p&gt;&lt;p&gt;I rarely let the rest of my application concern itself with the details of the service. Any other area of my application is simply asking for results based on input, regardless of how it is obtained. Therefore, I'll create a very light contract for the calculator service internally - one that is easy to mock and test.&lt;br /&gt;
&lt;p&gt;Create a folder called "Contract" and add one interface, &lt;code&gt;ICalculatorService&lt;/code&gt;. The interface looks like this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;namespace RxWebServices.Contract
{
    public interface ICalculatorService
    {
        IObservable&amp;lt;long&gt; Add(int operand1, int operand2);
    }
}
&lt;/pre&gt;&lt;p&gt;Here is where things get interesting. You should be familiar with &lt;code&gt;IEnumerable&lt;/code&gt; which we'll call a "pull" sequence of elements: you pull the values from the iterator. With Reactive Extensions, we invert this using &lt;code&gt;IObservable&lt;/code&gt; to create a "push" sequence. With the push sequence, you subscribe and receive an event (pushed to you) when an element is available. In this case, we'll subscribe by sending in two operands, and wait to be pushed the result when it comes back.&lt;br /&gt;
&lt;p&gt;&lt;i&gt;Wrapping the Service&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Now we've got a service proxy and an interface. Let's satisfy the contract. I'll show you the code, then explain it. Under the implementation folder, create a &lt;code&gt;Calculator.cs&lt;/code&gt; class and wire it up like this:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;namespace RxWebServices.Implementation
{
    [Export(typeof(ICalculatorService))]
    public class Calculator : ICalculatorService, IPartImportsSatisfiedNotification
    {
        [Import]
        public ICalculator CalculatorProxy { get; set; }

        private Func&amp;lt;int,int,IObservable&amp;lt;long&gt;&gt; _calculatorService;            

        public IObservable&amp;lt;long&gt; Add(int operand1, int operand2)
        {
            return _calculatorService(operand1, operand2);
        }

        public void OnImportsSatisfied()
        {
            _calculatorService = Observable.FromAsyncPattern&amp;lt;int, int, long&gt;
                (CalculatorProxy.BeginAdd, CalculatorProxy.EndAdd);
        }
    }
}
&lt;/pre&gt;&lt;p&gt;Let's break it down. First, you'll notice we import the calculator service. This is the actual proxy we set up in the previous class. When the import is satisfied, we use a helper method provided by Rx to convert the asynchronous call into an observable list. The &lt;code&gt;FromAsyncPattern&lt;/code&gt; takes in the types of the inputs, followed by the type of the output. It creates a function that, when called, returns an observable list of the results. In this case, we cast it from the beginning call to our calculator service to the return call. This is the way we take the asynchronous call and turn it into an observable list.&lt;br /&gt;
&lt;p&gt;When we actually want to use the method, we call the function with the inputs, and receive the output as the observable. Thus, we do all of the conversion internally, hide the implementation details, and just return a stream that can be subscribed to in order to fetch the results.&lt;br /&gt;
&lt;p&gt;Take a look at the signature for the actual service:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;private interface ICalculator
{
    IAsyncResult BeginAdd(int operand1, int operand2, AsyncCallback callback, object asyncState);
    
    long EndAdd(IAsyncResult result);
}
&lt;/pre&gt;&lt;p&gt;To use Rx, we want a function that takes all of the inputs up until the &lt;code&gt;AsyncCallback&lt;/code&gt; parameter, and returns an observable list of the return value. In this case, our two inputs are int, and it returns a long, so our function signature is &lt;code&gt;Func&amp;lt;int,int,IObservable&amp;lt;long&gt;&gt;&lt;/code&gt;. By using these same types on the &lt;code&gt;FromAsyncPattern&lt;/code&gt; extension method, Rx will return us the appropriate function and expect a pointer to the methods to start and the end the call.&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Fibonnacci Sequence&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Now we can get to the fun part: using the service. We'll use the service two different ways to illustrate how the observable lists work. In the &lt;code&gt;MainPage.xaml&lt;/code&gt;, add some rows, a set of buttons, and a stackpanel. Generate code behind for the buttons. It will look something like this:&lt;br /&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;Grid x:Name="LayoutRoot" Background="White"&gt;
    &amp;lt;Grid.RowDefinitions&gt;
        &amp;lt;RowDefinition Height="Auto"/&gt;
        &amp;lt;RowDefinition Height="*"/&gt;
    &amp;lt;/Grid.RowDefinitions&gt;
    &amp;lt;StackPanel Orientation="Horizontal" HorizontalAlignment="Center"&gt;
        &amp;lt;Button Content=" GO " Click="Button_Click" Margin="5"/&gt;
        &amp;lt;Button Content=" GO " Click="Button_Click_1" Margin="5"/&gt;
    &amp;lt;/StackPanel&gt;
    &amp;lt;StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="MainSurface"/&gt;
&amp;lt;/Grid&gt;
&lt;/pre&gt;&lt;p&gt;Next, let's go to the code behind and wire in the first example. First, we'll add some properties we're going to be using:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;[Import]
public ICalculatorService Calculator { get; set; }

private IDisposable _sequence;

private readonly Subject&amp;lt;long&gt; _watcher = new Subject&amp;lt;long&gt;();

private int _x, _y, _iterations;
&lt;/pre&gt;&lt;p&gt;The first piece is the service, which we import using MEF. When we subscribe to services, we receive a disposable observer. In order to cancel observations in progress and start new ones, we'll keep a reference to this using the &lt;code&gt;_sequence&lt;/code&gt; field. &lt;br /&gt;
&lt;p&gt;&lt;i&gt;What's Your Favorite Subject?&lt;/i&gt;&lt;/p&gt;&lt;p&gt;The subject is interesting. Subjects are used to set up a publisher/subscriber model. The subject here is a &lt;code&gt;long&lt;/code&gt;. Anyone with access to the subject can publish (send it a long value) and/or subscribe (receive notifications when values are published). We'll use this to bridge between our UI and the service.&lt;br /&gt;
&lt;p&gt;Finally, we've got some local variables to use to keep track of state.&lt;br /&gt;
&lt;p&gt;Next, we'll set everything up in the constructor:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public MainPage()
{
    InitializeComponent();

    if (DesignerProperties.IsInDesignTool) return;

    CompositionInitializer.SatisfyImports(this);

    _watcher.ObserveOnDispatcher().Subscribe(
        answer =&gt;
            {
                var grid = new Grid
                                {
                                    Width = answer,
                                    Height = answer,
                                    Background = new SolidColorBrush(Colors.Red),
                                    Margin = new Thickness(5, 5, 5, 5)
                                };
                var tb = new TextBlock {Margin = new Thickness(2, 2, 2, 2), Text = answer.ToString()};
                grid.Children.Add(tb);
                MainSurface.Children.Add(grid);
                _Add();
            });
}
&lt;/pre&gt;&lt;p&gt;The first thing you'll notice is that if we're in the designer, all bets are off and we drop out. Otherwise, we compose the parts, which gives us our service import. Next, we'll subscribe to our subject. Notice that we don't have any service interaction yet. The subscription basically breaks down like this:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I'm interested in the subject with long values&lt;li&gt;When something happens, let me know on the dispatcher thread (as I'm going to do something with the UI)&lt;li&gt;When a long value is observed, give it to me: I'll make a grid as big as the value I received, put some text inside it, add it to the stack panel and then call the &lt;code&gt;_Add&lt;/code&gt; method&lt;/ul&gt;&lt;p&gt;That's very simple and straightforward. No we can explore the missing method. First, let's kick things off when the user clicks the first button. I want to use the add service to compute a fibonnacci ratio (each number is the sum of the previous two, started with 1 and 1). I'll implement the button click code-behind and add the missing method here:
&lt;pre class="brush: csharp;"&gt;private void Button_Click(object sender, RoutedEventArgs e)
{
    if (_sequence != null)
    {
        _sequence.Dispose();
    }

    MainSurface.Children.Clear();

    _x = 1;
    _y = 1;
    _iterations = 0;

    _watcher.OnNext(_x);            
}      
  
private void _Add()
{         
    _sequence.Dispose();

    if (++_iterations == 20)
    {
        return;
    }

    _sequence = Calculator.Add(_x, _y).Subscribe(answer =&gt;
                                            {
                                                _x = _y;
                                                _y = (int)answer;
                                                _watcher.OnNext(answer);                                                     
                                            });
}
&lt;/pre&gt;&lt;p&gt;So the first part should be straight forward. If we had another sequence, dispose it. This will cancel any observations in progress. Clear the surface, initialize our variables, and then call the &lt;code&gt;OnNext&lt;/code&gt; function on our subject. What's that? Simple: we just published a number. The subject will receive the number (1) and then push it to any subscriptions. We subscribed earlier, so we'll create a 1x1 grid and call the &lt;code&gt;_Add&lt;/code&gt; method. 
&lt;p&gt;This method is even more interesting. First, we stop after 20 iterations. No sense in going to infinity. Next, we subscribe to the calculator service. Subscriptions to observable lists are the same as subscriptions to subjects. We're asking to watch for a value, and initiating the "watch" by sending in our first values (1 and 1). When we receive the answer, we shift the numbers to continue the sequence, and then publish the number to the subject. 
&lt;p&gt;This allows us to "daisy chain" service calls. We wait until we receive the first answer before we ask the next question. At this point, if you hit F5 (or CTRL-F5) to run it, and click the first button, you should see this:
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=336&amp;g2_serialNumber=1"/&gt;
&lt;p&gt;Note if you keep clicking while it is rendering, it will start over. There will be no "hanging" calls because the calls are daisy chained. We are also not blocking the UI while waiting, or you wouldn't be able to click the button again. You can clearly see the delays on the server as the results are returned.
&lt;p&gt;Here is a simplified overview of what is happening:
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=339&amp;g2_serialNumber=2"/&gt; 
&lt;p&gt;&lt;b&gt;Random Addition&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Now we'll throw another function into the mix. It's time to set up the second button. For this button, we're going to add two methods. The first is an enumerable that returns nothing but random numbers. It loops infinitely so we obtain as many numbers as we like, and we'll receive them in tuples:
&lt;pre class="brush: csharp;"&gt;private static IEnumerable&amp;lt;Tuple&amp;lt;int,int&gt;&gt; _RandomNumbers()
{
    var random = new Random();

    while (true)
    {
        yield return Tuple.Create(random.Next(100), random.Next(100));                
    }
}
&lt;/pre&gt;&lt;p&gt;In the event handler for the second button, add this bit of code:
&lt;pre class="brush: csharp;"&gt;private void Button_Click_1(object sender, RoutedEventArgs e)
{
    if (_sequence != null)
    {
        _sequence.Dispose();
    }

    MainSurface.Children.Clear();

    _sequence = _RandomNumbers()
        .ToObservable()
        .Take(20)                
        .Subscribe(numbers =&gt; Calculator.Add(numbers.Item1, numbers.Item2)
                                    .ObserveOnDispatcher()
                                    .Subscribe(result =&gt;
                                                    {
                                                        var text = string.Format("{0}+{1}={2}", numbers.Item1,
                                                                                numbers.Item2, result);
                                                        var tb = new TextBlock
                                                                    {Margin = new Thickness(5, 5, 5, 5), Text = text};
                                                        MainSurface.Children.Add(tb);
                                                    }));                
}    
&lt;/pre&gt;&lt;p&gt;This is a little different. First, we're taking the enumerable list of random numbers and turning it into an observable list so the values will be pushed to us. This is just by way of demonstration; we could have just as easily iterated the list with a foreach loop instead. What's interesting here is that I can limit how many I grab with the &lt;code&gt;Take(20)&lt;/code&gt; extension. I subscribe like I do to any other observable list, and when I receive the next number pair, I turn around and subscribe to the calculator service to add the numbers for me. Instead of publishing the result to the subject, I'm handling it myself. I observe on the dispatcher thread, then add a text block with the addition statement to the stack panel.
&lt;p&gt;Go ahead and run the application, click the button, and you'll receive output that looks like this:
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=341&amp;g2_serialNumber=1"/&gt;
&lt;p&gt;&lt;b&gt;Observations (Pardon the Pun)&lt;/b&gt;&lt;/p&gt;&lt;p&gt;If you run this and click the go button, you might notice something interesting. No matter how many times you click, you get the full sequence
of numbers. In other words, if I let 5 numbers come back, then click go, I'll receive a sequence of 35 numbers, not 25. 
&lt;p&gt;Even more interesting is if you click the second go button, wait until most (but not all) of the 20 numbers return, then click the first go button. You'll see the screen clear, but you'll receive a few sequences of added numbers before the fibonnacci sequence starts.
&lt;p&gt;&lt;i&gt;What's Going On?&lt;/i&gt;&lt;p&gt;&lt;p&gt;But we disposed of the subscription, right? Not exactly. In this implementation, we always getting the same service subscription. The subscription we cancel is the &lt;i&gt;outer&lt;/i&gt; observation. To better understand this, load up a tool like Fiddler and watch the service calls. In the first example, the call is made, there is a delay, it returns, and then the next call is made.
&lt;p&gt;In the second example, however, almost all of the calls are made almost all at once. They return at different rates due to the delays on the server. So, when you start a new sequence, you subscribe to the same service and therefore get to watch the results return that hadn't made it back from the initial calls.
&lt;p&gt;This is important to understand as you are building your extensions, because in some cases you might want a new observable sequence, while in others it makes sense to keep the existing one. It depends on your needs and the desired behavior.
&lt;p&gt;Hopefully this will help open some new doors of understanding about Reactive Extensions! 
&lt;p&gt;&lt;a href="http://www.wintellect.com/CS/files/folders/sample_files/entry18142.aspx" target="_blank"&gt;Click here to download the source code for this article&lt;/a&gt;
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-3149516175558268919?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/3149516175558268919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/simplifying-silverlight-web-service.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/3149516175558268919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/3149516175558268919'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/simplifying-silverlight-web-service.html' title='Simplifying Silverlight Web Service Calls with Reactive Extensions (Rx)'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-936086542275102748</id><published>2010-08-17T17:55:00.000-04:00</published><updated>2010-08-17T17:55:05.755-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Managed Extensibility Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='quickstart'/><title type='text'>Managed Extensibility Framework Quickstart: Hello, MEF</title><content type='html'>&lt;p&gt;I've been working on quickstarts for a community team that I'm a member of. The team is called &lt;a href="http://www.mefcontrib.com/" target="_blank"&gt;MEFContrib&lt;/a&gt;. We write extensions to the Managed Extensibility Framework as well as supporting manuals and documentation. I've been tasked with the quickstarts and as I release them I'll post them for you. &lt;br /&gt;
&lt;p&gt;Obviously, a quickstart should be, well, quick, and easy. We also decided quickstarts would be independent so that you can jump into any topic without having to read the prior ones. Today's post is simply a "Hello, MEF" for a quick introduction to using MEF. I will also follow up with a version specifically for Silverlight.&lt;br /&gt;
&lt;p&gt;I've embedded the quickstart video below, and you can read the full article (with video included) by &lt;a href="http://mefcontrib.com/hello,-mef.aspx" target="_blank"&gt;clicking here&lt;/a&gt;.&lt;br /&gt;
&lt;p&gt;Enjoy!&lt;br /&gt;
&lt;p&gt;&lt;div id="silverlightControlHost"&gt;&lt;object data="data:application/x-silverlight," type="application/x-silverlight-2" class="embeddedObject" width="640" height="480"&gt;      &lt;param name="source" value="http://content.screencast.com/users/MEFContrib/folders/Default/media/92798806-6ed3-4a90-b9e8-3955f9337660/wmvplayer.xap"/&gt;&lt;param name="onerror" value="onSilverlightError" /&gt;&lt;param name="background" value="#202020" /&gt;&lt;param name="minRuntimeVersion" value="2.0.31005.0" /&gt;&lt;param name="autoUpgrade" value="true" /&gt;&lt;param name="initParams" value="content=http://content.screencast.com/users/MEFContrib/folders/Default/media/92798806-6ed3-4a90-b9e8-3955f9337660/mefquickstart1.wmv,thumb=http://content.screencast.com/users/MEFContrib/folders/Default/media/92798806-6ed3-4a90-b9e8-3955f9337660/FirstFrame.jpg,showtoc=false,showsearch=false,showBranding=false" /&gt;&lt;object name="Video" type="video/x-ms-wmv"     width="640" height="480" data="http://content.screencast.com/users/MEFContrib/folders/Default/media/92798806-6ed3-4a90-b9e8-3955f9337660/mefquickstart1.wmv"&gt;    &lt;param name="url" value="http://content.screencast.com/users/MEFContrib/folders/Default/media/92798806-6ed3-4a90-b9e8-3955f9337660/mefquickstart1.wmv"&gt;&lt;/param&gt;&lt;param name="src" value="http://content.screencast.com/users/MEFContrib/folders/Default/media/92798806-6ed3-4a90-b9e8-3955f9337660/mefquickstart1.wmv"&gt;&lt;/param&gt;&lt;param name="AutoStart" value="true"&gt;&lt;/param&gt;&lt;param name="ShowControls" value="true"&gt;&lt;/param&gt;&lt;param name="uiMode" value="full"&gt;&lt;/param&gt;&lt;param name="playCount" value="1"&gt;&lt;/param&gt;&lt;param name="CurrentPosition" value="0"&gt;&lt;/param&gt;&lt;p&gt;Viewing this content requires Silverlight.  You can download Silverlight from &lt;a href="http://www.silverlight.net/getstarted/silverlight3/" target="_blank"&gt;http://www.silverlight.net/getstarted/silverlight3&lt;/a&gt;.&lt;/p&gt;&lt;/object&gt; &lt;/object&gt;   &lt;iframe style="visibility:hidden;height:0;width:0;border:0px"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-936086542275102748?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://mefcontrib.com/hello,-mef.aspx' title='Managed Extensibility Framework Quickstart: Hello, MEF'/><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/936086542275102748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/managed-extensibility-framework.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/936086542275102748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/936086542275102748'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/managed-extensibility-framework.html' title='Managed Extensibility Framework Quickstart: Hello, MEF'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-4142577976139872109</id><published>2010-08-10T13:50:00.001-04:00</published><updated>2010-08-10T13:50:34.285-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='command'/><title type='text'>Sharing Silverlight Commands with the Managed Extensibility Framework</title><content type='html'>&lt;p&gt;View models can expose commands that are bound to controls. Commands encapsulate an action and a permission, and the advantage to binding is that controls that support commands will automatically disable when the command cannot execute. Commands can also be easily added to view models and tested. &lt;br /&gt;
&lt;p&gt;It is common to find commands that are used universally. In Windows Presentation Foundation (WPF), this is managed by a set of global commands that can be accessed via static classes. Silverlight does not provide the equivalent, but it is easy enough to compose and share commands using MEF.&lt;br /&gt;
&lt;p&gt;There were specifically two scenarios I needed to tackle in a recent project.&lt;br /&gt;
&lt;p&gt;&lt;b&gt;The First Scenario: Command Sharing&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;It is quite common to have a command that can be executed from multiple places. An "expand" command, for example, represents a generic behavior that is applied to specific controls. If the behavior can be extrapolated from the control itself, why duplicate it across multiple controls? It is far more efficient to define the behavior in one place and then share the behavior where it is needed.&lt;br /&gt;
&lt;p&gt;&lt;b&gt;The Second Scenario: Late Command Binding&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;Sometimes commands may provide a layer of de-coupling. Specifically, I wanted to provide a command to switch to a different type of view. Because my view models are shared by different views, I didn't want to create a tight coupling by referencing the views directly. In fact, the views were being dynamically loaded in a separate XAP file, so there was no reference I could create in the view model. To solve this I used MEF to late-bind the command when the view becomes available.&lt;br /&gt;
&lt;p&gt;&lt;b&gt;The Setup&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;The setup is quite simple. Because I want to import the command directly, I'm not going to use metadata. Instead, I'll create a common static class that is shared across my project that exposes some constants to define the commands. I'll use the constants as the contract name for importing and exporting. It looks like this: &lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public static class Commands 
{
   public const string EXPORT_COMMAND = "ExportCommand";
}
&lt;/pre&gt;&lt;p&gt;Now I can request the command in my view model, by importing it directly: &lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public class MyViewModel
{
   [Import(Commands.EXPORT_COMMAND, AllowDefault=true)]
   public DelegateCommand&amp;lt;object&gt; ImportedCommand { get; set; }
}
&lt;/pre&gt;&lt;p&gt;The "allow default" is important. If I don't have the command available, MEF will throw an exception when trying to set the import. With allow default, the property simply remains as null until the import can be satisfied. Once my dynamic module loads with the corresponding export, it will be wired in for me. Note that I can import the same command in multiple places to satisfy the need to share it.&lt;br /&gt;
&lt;p&gt;Now I can export the command. I might create a class specifically for this or place it in a view model in the imported XAP file. Regardless, an exported command looks something like this: &lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public class Exports
{
   [Import]
   public INavigation Navigation { get; set; }

   [Export(Commands.EXPORT_COMMAND)]
   public DelegateCommand&amp;lt;object&gt; ExportedCommand 
   {
      get 
      {
         return new DelegateCommand&amp;lt;object&gt;(
            obj =&gt; Navigation.NavigateTo(typeof(SomeView)));
      }
   }
}
&lt;/pre&gt;&lt;p&gt;This way I'm able to expose a command for navigation without knowing what the view or navigation looks like ... instead, I let the XAP that does know handle it for me.&lt;br /&gt;
&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-4142577976139872109?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/4142577976139872109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/sharing-commands-with-managed.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/4142577976139872109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/4142577976139872109'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/sharing-commands-with-managed.html' title='Sharing Silverlight Commands with the Managed Extensibility Framework'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-5475991455746376943</id><published>2010-04-14T14:30:00.006-04:00</published><updated>2010-08-08T10:46:00.531-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvvm'/><category scheme='http://www.blogger.com/atom/ns#' term='wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='model-view-viewmodel'/><category scheme='http://www.blogger.com/atom/ns#' term='composite wpf'/><category scheme='http://www.blogger.com/atom/ns#' term='model-view-presenter'/><category scheme='http://www.blogger.com/atom/ns#' term='model-view-controller'/><title type='text'>Model-View-ViewModel (MVVM) Explained</title><content type='html'>&lt;p&gt;The purpose of this post is to provide an introduction to the Model-View-ViewModel (MVVM) pattern. While I've participated in lots of discussions online about MVVM, it occurred to me that beginners who are learning the pattern have very little to go on and a lot of conflicting resources to wade through in order to try to implement it in their own code. I am not trying to introduce dogma but wanted to pull together key concepts in a single post to make it easy and straightforward to understand the value of the pattern and how it can be implemented. MVVM is really far simpler than people make it out to be. &lt;p&gt;&lt;b&gt;&lt;a href="http://maromasdigitales.net/2010/05/patron-mvvm-explicado/" target="_blank"&gt;Click here to read the Spanish version (Leer en español)&lt;/a&gt;&lt;/b&gt; &lt;p&gt;&lt;b&gt;Why Even Care About MVVM?&lt;/b&gt; &lt;p&gt;Why should you, as a developer, even care about the Model-View-ViewModel pattern? There are a number of benefits this pattern brings to both WPF and Silverlight development. Before you go on, ask yourself:  &lt;ul&gt;&lt;li&gt;Do you need to share a project with a designer, and have the flexibility for design work and development work to happen near-simultaneously?&lt;br /&gt;
&lt;li&gt;Do you require thorough unit testing for your solutions?&lt;br /&gt;
&lt;li&gt;Is it important for you to have reusable components, both within and across projects in your organization?&lt;br /&gt;
&lt;li&gt;Would you like more flexibility to change your user interface without having to refactor other logic in the code base?&lt;/ul&gt;&lt;p&gt;If you answered "yes" to any of these questions, these are just a few of the benefits that using the MVVM model can bring for your project. &lt;p&gt;I've been amazed at some conversations I've read online. Things like, "MVVM only makes sense for extremely complex UI" or "MVVM always adds a lot of overhead and is too much for smaller applications." The real kicker was, "MVVM doesn't scale." In my opinion, statements like this speak to knowledge and implementation of MVVM, not MVVM itself. In other words, if you think it takes hours to wire up MVVM, you're not doing it right. If your application isn't scaling, don't blame MVVM, blame how you are using MVVM. Binding 100,000 items to a list box can be just silly regardless of what pattern you are following.  &lt;p&gt;So the quick disclaimer: this is MVVM as I know it, not MVVM as a universal truth. I encourage you to share your thoughts, experiences, feedback, and opinions using the comments. If you feel something is incorrect, let me know and I'll do my best to keep this post updated and current. &lt;p&gt;&lt;b&gt;MVVM at a Glance&lt;/b&gt; &lt;p&gt;Let's examine the pieces of the MVVM pie. We'll start with the basic building block that is key for all applications: data and information. This is held in the model. &lt;p&gt;&lt;i&gt;The Model&lt;/i&gt;&lt;img src="http://jeremylikness.com/images/silhouette.jpg" style="margin: 5px;" align="right"/&gt; &lt;p&gt;The model is what I like to refer to as the domain object. The model represents the actual data and/or information we are dealing with. An example of a model might be a contact (containing name, phone number, address, etc) or the characteristics of a live streaming publishing point.  &lt;p&gt;The key to remember with the model is that it holds the information, but not behaviors or services that manipulate the information. It is not responsible for formatting text to look pretty on the screen, or fetching a list of items from a remote server (in fact, in that list, each item would most likely be a model of its own). Business logic is typically kept separate from the model, and encapsulated in other classes that act on the model. This is not always true: for example, some models may contain validation. &lt;p&gt;It is often a challenge to keep a model completely "clean." By this I mean a true representation of "the real world." For example, a contact record may contain a last modified date and the identity of the modifying user (auditing information), and a unique identifier (database or persistence information). The modified date has no real meaning for a contact in the real world but is a function of how the model is used, tracked, and persisted in the system. &lt;p&gt;Here is a sample model for holding contact information:  &lt;pre class="brush: csharp;"&gt;namespace MVVMExample
{
    public class ContactModel : INotifyPropertyChanged
    {
        private string _firstName;

        public string FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = value;
                RaisePropertyChanged("FirstName");
                RaisePropertyChanged("FullName");
            }
        }

        private string _lastName;

        public string LastName
        {
            get { return _lastName; }
            set
            {
                _lastName = value;
                RaisePropertyChanged("LastName");
                RaisePropertyChanged("FullName");
            }
        }

        public string FullName
        {
            get { return string.Format("{0} {1}", FirstName, LastName); }
        }

        private string _phoneNumber;

        public string PhoneNumber
        {
            get { return _phoneNumber; }
            set
            {
                _phoneNumber = value;
                RaisePropertyChanged("PhoneNumber");
            }
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public override bool Equals(object obj)
        {
            return obj is ContactModel &amp;&amp; ((ContactModel) obj).FullName.Equals(FullName);
        }

        public override int GetHashCode()
        {
            return FullName.GetHashCode();
        }
    }
}
&lt;/pre&gt;&lt;br clear="all"/&gt; &lt;p&gt;&lt;i&gt;The View&lt;/i&gt; &lt;p&gt;&lt;img src="http://jeremylikness.com/images/view.jpg"/&gt; &lt;p&gt;The view is what most of us are familiar with and the only thing the end user really interacts with. It is the presentation of the data. The view takes certain liberties to make this data more presentable. For example, a date might be stored on the model as number of seconds since midnight on January 1, 1970 (&lt;a href="http://en.wikipedia.org/wiki/Unix_time" target="_blank"&gt;Unix Time&lt;/a&gt;). To the end user, however, it is presented with the month name, date, and year in their local time zone. A view can also have behaviors associated with it, such as accepting user input. The view manages input (key presses, mouse movements, touch gestures, etc) which ultimately manipulates properties of the model. &lt;p&gt;In MVVM, the view is active. As opposed to a &lt;i&gt;passive view&lt;/i&gt; which has no knowledge of the model and is completely manipulated by a controller/presenter, the view in MVVM contains behaviors, events, and data-bindings that ultimately require knowledge of the underlying model and viewmodel. While these events and behaviors might be mapped to properties, method calls, and commands, the view is still responsible for handling it's own events and does not turn this completely over to the viewmodel. &lt;p&gt;One thing to remember about the view is that it is &lt;i&gt;not&lt;/i&gt; responsible for maintaining its state. Instead, it will synchronize this with the viewmodel. &lt;p&gt;Here is an example view, expressed as XAML: &lt;pre class="brush: xml;"&gt;&amp;lt;UserControl x:Class="MVVMExample.DetailView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    &amp;lt;Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding CurrentContact}"&gt;
        &amp;lt;Grid.RowDefinitions&gt;
            &amp;lt;RowDefinition/&gt;
            &amp;lt;RowDefinition/&gt;
        &amp;lt;/Grid.RowDefinitions&gt;
        &amp;lt;Grid.ColumnDefinitions&gt;
            &amp;lt;ColumnDefinition/&gt;
            &amp;lt;ColumnDefinition/&gt;
        &amp;lt;/Grid.ColumnDefinitions&gt;
        &amp;lt;TextBlock Text="Name:" HorizontalAlignment="Right" Margin="5"/&gt;
        &amp;lt;TextBlock Text="{Binding FullName}" HorizontalAlignment="Left" Margin="5" Grid.Column="1"/&gt;
        &amp;lt;TextBlock Text="Phone:" HorizontalAlignment="Right" Margin="5" Grid.Row="1"/&gt;
        &amp;lt;TextBlock Text="{Binding PhoneNumber}" HorizontalAlignment="Left" Margin="5" Grid.Row="1" Grid.Column="1"/&gt;
    &amp;lt;/Grid&gt;
&amp;lt;/UserControl&gt;
&lt;/pre&gt;&lt;p&gt;Note that the various bindings are the integration/synchronization points with the viewmodel. &lt;br clear="all"/&gt;  &lt;p&gt;&lt;i&gt;The ViewModel (Our Controller/Presenter)&lt;/i&gt;&lt;img src="http://jeremylikness.com/images/controller.jpg" style="margin: 5px;" align="right"/&gt; &lt;p&gt;The viewmodel is a key piece of the triad because it introduces &lt;i&gt;Presentation Separation&lt;/i&gt;, or the concept of keeping the nuances of the view separate from the model. Instead of making the model aware of the user's view of a date, so that it converts the date to the display format, the model simply holds the data, the view simply holds the formatted date, and the controller acts as the liaison between the two. The controller might take input from the view and place it on the model, or it might interact with a service to retrieve the model, then translate properties and place it on the view.  &lt;p&gt;The viewmodel also exposes methods, commands, and other points that help maintain the state of the view, manipulate the model as the result of actions on the view, and trigger events in the view itself. &lt;p&gt;MVVM, while it evolved "behind the scenes" for quite some time, was introduced to the public in 2005 via Microsoft's John Gossman blog post about Avalon (the code name for Windows Presentation Foundation, or WPF). The blog post is entitled, &lt;a href="http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx" target="_blank"&gt;Introduction to Model/View/ViewModel pattern for building WPF Apps&lt;/a&gt; and generated quite a stir judging from the comments as people wrapped their brains around it. &lt;p&gt;I've heard MVVM described as an implementation of &lt;a href="http://martinfowler.com/eaaDev/PresentationModel.html" target="_blank"&gt;Presentation Model&lt;/a&gt; designed specifically for WPF (and later, Silverlight).  &lt;p&gt;The examples of the pattern often focus on XAML for the view definition and data-binding for commands and properties. These are more &lt;i&gt;implementation details&lt;/i&gt; of the pattern rather than intrinsic to the pattern itself, which is why I offset data-binding with a different color: &lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=246&amp;g2_serialNumber=1" alt="Model-View-ViewModel" title="Model-View-ViewModel"/&gt; &lt;p&gt;Here is what a sample view model might look like. We've created a &lt;code&gt;BaseINPC&lt;/code&gt; class (for "INotifyPropertyChanged") that has a method to make it easy for raising the property changed event.  &lt;pre class="brush: csharp;"&gt;namespace MVVMExample
{
    public class ContactViewModel : BaseINPC
    {
        public ContactViewModel()
        {
            Contacts = new ObservableCollection&amp;lt;ContactModel&gt;();
            Service = new Service();
            
            Service.GetContacts(_PopulateContacts);

            Delete = new DeleteCommand(
                Service, 
                ()=&amp;gt;CanDelete,
                contact =&amp;gt;
                    {
                        CurrentContact = null;
                        Service.GetContacts(_PopulateContacts);
                    });
        }

        private void _PopulateContacts(IEnumerable&amp;gt;ContactModel&gt; contacts)
        {
            Contacts.Clear();
            foreach(var contact in contacts)
            {
                Contacts.Add(contact);
            }
        }

        public IService Service { get; set; }

        public bool CanDelete
        {
            get { return _currentContact != null; }
        }

        public ObservableCollection&amp;lt;ContactModel&gt; Contacts { get; set; }

        public DeleteCommand Delete { get; set; }

        private ContactModel _currentContact;

        public ContactModel CurrentContact
        {
            get { return _currentContact; }
            set
            {
                _currentContact = value;
                RaisePropertyChanged("CurrentContact");
                RaisePropertyChanged("CanDelete");
                Delete.RaiseCanExecuteChanged();
            }
        }
    }
}
&lt;/pre&gt;&lt;p&gt;This view model is obviously designed to manage a list of contacts. It also exposes a delete command and a flag to indicate whether delete is allowed (thus maintaining state for the view). Often the flag would be part of the command object, but the example is in Silverlight 3 which does not have native support for command binding, and I wanted to show a simple solution that didn't require a fancy framework. (Take a look at &lt;a href="http://csharperimage.jeremylikness.com/2010/04/converting-silverlight-3-to-silverlight.html" target="_blank"&gt;this video&lt;/a&gt; to see how easy it is to convert the example from Silverlight 3 to Silverlight 4 and use native commanding instead). The view model here makes a concrete reference to the service.  &lt;p&gt;For larger applications, I prefer to wire in that reference externally or use a dependency injection framework. What's nice is we have the flexibility to build it like this initially and then refactor as needed - again, you do not have to use any of these frameworks to take advantage of the pattern, as you can see from this example. It fetches the list of "contacts" right away, which is a hard-coded list of me and someone a little more popular. The phone numbers, of course, are faked.  &lt;p&gt;Let's get a little more specific and look at how this would be implemented in a sample application. Here is what an X-ray of a sample MVVM set up may look like:  &lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=242&amp;g2_serialNumber=2" title="MVVM Explained" alt="MVVM Explained"/&gt; &lt;p&gt;So what can we gather from this snapshot?  &lt;p&gt;First, the &lt;code&gt;IConfig&lt;/code&gt; represents a configuration service (in a newsreader it may contain the account information and feeds that are being fetched), while the &lt;code&gt;IService&lt;/code&gt; is "some service" - perhaps the interface to fetch feeds from RSS sources in a news reader application.  &lt;p&gt;&lt;b&gt;The View and the ViewModel&lt;/b&gt; &lt;ul&gt;&lt;li&gt;The view and the viewmodel communicate via data-binding, method calls, properties, events, and messages&lt;br /&gt;
&lt;li&gt;The viewmodel exposes not only models, but other properties (such as state information, like the "is busy" indicator) and commands&lt;br /&gt;
&lt;li&gt;The view handles its own UI events, then maps them to the viewmodel via commands&lt;br /&gt;
&lt;li&gt;The models and properties on the viewmodel are updated from the view via two-way databinding&lt;/ul&gt;&lt;p&gt;Two mechanisms that often factor into implementations of the pattern are triggers (especially data triggers) in WPF, and the Visual State Manager (VSM) in Silverlight. These mechanisms help implement the pattern by binding UI behaviors to the underlying models. In Silverlight, the VSM should be the primary choice for coordination of transitions and animations. &lt;a href="http://blogs.silverlight.net/blogs/justinangel/archive/2008/12/25/custom-vsm-visualstatemanagers-in-silverlight-2-0.aspx" target="_blank"&gt;Learn more about VSM&lt;/a&gt;. &lt;p&gt;&lt;b&gt;The ViewModel and the Model&lt;/b&gt; &lt;p&gt;The viewmodel becomes wholly responsible for the model in this scenario. Fortunately, it's not alone:&lt;ul&gt;&lt;li&gt;The viewmodel may expose the model directly, or properties related to the model, for data-binding&lt;br /&gt;
&lt;li&gt;The viewmodel can contain interfaces to services, configuration data, etc in order to fetch and manipulate the properties it exposes to the view&lt;/ul&gt;&lt;p&gt;&lt;b&gt;The Chicken or the Egg?&lt;/b&gt; &lt;p&gt;You might have heard discussion about &lt;i&gt;view first&lt;/i&gt; or &lt;i&gt;viewmodel first&lt;/i&gt;. In general, I believe most developers agree that a view should have exactly one viewmodel. There is no need to attach multiple viewmodels to a single view. If you think about separation of concerns, this makes sense, because if you have a "contact widget" on the screen bound to a "contact viewmodel" and a "company widget" bound to a "company viewmodel", these should be separate views, not a single view with two viewmodels.  &lt;p&gt;A view may be composed of other views, each with its own viewmodel. Viewmodels might compose other viewmodels when necessary (often, however, I see people &lt;a href="http://csharperimage.jeremylikness.com/2009/12/mvvm-composition-in-silverlight-3-with.html" target="_blank"&gt;composing and aggregating viewmodels&lt;/a&gt; when in fact what they really want is messaging between viewmodels).  &lt;p&gt;While a view should only have one viewmodel, a single viewmodel might be used by multiple views (imagine a wizard, for example, that has three views but all bind to the same viewmodel that drives the process).  &lt;p&gt;&lt;i&gt;View First&lt;/i&gt; &lt;p&gt;View first simply means the view is what drives the creation or discovery of the view model. In view first scenarios, the view typically binds to the view model as a resource, uses a locator pattern, or has the view model injected via MEF, Unity, or some other means. This is a very common method for managing views and view models. Here are some of my posts on the topic: &lt;ul&gt;&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2010/03/viewmodel-binding-with-managed.html" target="_blank"&gt;ViewModel Binding with MEF&lt;/a&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2009/12/mvvm-composition-in-silverlight-3-with.html" target="_blank"&gt;MVVM Composition in Silverlight with Prism&lt;/a&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2009/12/prism-mef-and-mvvm-part-1-of-3-unity.html" target="_blank"&gt;Prism, MEF, and MVVM&lt;/a&gt;&lt;/ul&gt;&lt;p&gt;The example I've included with this post is view-first. The view is created, then the view model attached. In the &lt;code&gt;App&lt;/code&gt; object, it looks like this:  &lt;pre class="brush: csharp;"&gt;private void Application_Startup(object sender, StartupEventArgs e)
{
    var shell = new MainPage();
    shell.LayoutRoot.DataContext = new ContactViewModel();
    RootVisual = shell;
}
&lt;/pre&gt;&lt;p&gt;In this example, I'm keeping it simple and not using any frameworks to wire in interfaces and implementations. &lt;p&gt;&lt;i&gt;ViewModel First&lt;/i&gt; &lt;p&gt;ViewModel first is another method to wire the framework together. In this scenario, the viewmodel is responsible for creating the view and binding itself to the view. You can see an example of this in Rob Eisenberg's convention-based framework he discussed at MIX:  &lt;a href="http://live.visitmix.com/MIX10/Sessions/EX15" target="_blank"&gt;Build your own MVVM Framework&lt;/a&gt;.  &lt;p&gt;The take away here is there are multiple ways to skin the cat.  &lt;p&gt;&lt;b&gt;A Basic MVVM Framework&lt;/b&gt; &lt;p&gt;In my opinion, a basic MVVM framework really only requires two things:&lt;ol&gt;&lt;li&gt;A class that is either a &lt;code&gt;DependencyObject&lt;/code&gt; or implements &lt;code&gt;INotifyPropertyChanged&lt;/code&gt; to fully support data-binding, and&lt;br /&gt;
&lt;li&gt;Some sort of commanding support.&lt;/ol&gt;&lt;p&gt;The second issue exists in Silverlight 3 because the &lt;code&gt;ICommand&lt;/code&gt; interface is provided, but not implemented. In Silverlight 4 commanding is more "out of the box." Commands facilitate binding of events from the view to the viewmodel. These are implementation details that make it easier to use the MVVM pattern. &lt;p&gt;Keep in mind there is very rich support for binding and behaviors in Blend and the free Blend SDK. You can watch my video, &lt;a href="http://csharperimage.jeremylikness.com/2010/03/mvvm-with-mef-in-silverlight-video.html" target="_blank"&gt;MVVM with MEF in Silverlight&lt;/a&gt;, to get an idea of how easy it really is to implement the MVVM pattern even without an existing framework in place. The post, &lt;a href="http://csharperimage.jeremylikness.com/2010/02/mef-instead-of-prism-for-silverlight-3.html" target="_blank"&gt;MEF instead of Prism for Silverlight 3&lt;/a&gt;, shows how to build your own command objects.  &lt;p&gt;With this example, I created a base class to handle the property changed events: &lt;pre class="brush: csharp;"&gt;namespace MVVMExample
{
    public abstract class BaseINPC : INotifyPropertyChanged  
    {
        protected void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged; 

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

&lt;/pre&gt;&lt;p&gt;I also implemented a command. Typically you would have a more generic type of command to handle different situations, but again, for the sake of illustration, I simply created a delete command specific to the function it performs. I am using a message box to confirm the delete. If you require something more elegant like a &lt;code&gt;ChildWindow&lt;/code&gt;, read the scenarios I describe below to better understand how to integrate a dialog box as a service within MVVM.  &lt;pre class="brush: csharp;"&gt;namespace MVVMExample
{
    public class DeleteCommand : ICommand 
    {
        private readonly IService _service;
        private readonly Func&amp;lt;bool&gt; _canExecute;
        private readonly Action&amp;lt;ContactModel&gt; _deleted;

        public DeleteCommand(IService service, Func&amp;lt;bool&gt; canExecute, Action&amp;lt;ContactModel&gt; deleted)
        {
            _service = service;
            _canExecute = canExecute;
            _deleted = deleted;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute();
        }

        public void Execute(object parameter)
        {
            if (CanExecute(parameter))
            {
                var contact = parameter as ContactModel; 
                if (contact != null)
                {
                    var result = MessageBox.Show("Are you sure you wish to delete the contact?",
                                                              "Confirm Delete", MessageBoxButton.OKCancel);

                    if (result.Equals(MessageBoxResult.OK))
                    {
                        _service.DeleteContact(contact);
                        if (_deleted != null)
                        {
                            _deleted(contact);
                        }
                    }
                }
            }
        }

        public void RaiseCanExecuteChanged()
        {
            var handler = CanExecuteChanged;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }

        public event EventHandler CanExecuteChanged;
    }
}
&lt;/pre&gt;&lt;p&gt;This particular command uses a delegate to callback when it is done, but this would only allow for a single subscriber. A multicast delegate or event will be required if multiple consumers (or viewmodels) for the command exist.  &lt;p&gt;In Silverlight 4, I can simply bind a button to the command using the &lt;code&gt;Command&lt;/code&gt; tag. I built the example in Silverlight 3, which does not have native support. To create the binding, I made a simple trigger - again, specific to this project and for the sake of illustration - to invoke the command, so I can easily bind it in the XAML.  &lt;p&gt;For the examples I've provided here, you can view the sample application. It is very simple and contains exactly one service and one view model with a "mock database." Two views bind to the same viewmodel, and you can click on a contact to see its details. You can also delete a contact.  &lt;p&gt;I often receive complaints that blog examples are too simple. This is sufficiently complex to show a full app without depending on other frameworks, but certainly doesn't show multiple pages and types of views. The reason you don't see these as often from me is simply because I am a consultant and contractor, so I am constantly building these line of business frameworks and applications for customers, and am not at liberty to share their code. While I can build small examples for posts, I simply don't have the time to build a larger working model. It's something I'd certainly like to do, but just wasn't practical for the timing of this post.  &lt;p&gt;You can download the source code for this example &lt;a href="http://www.wintellect.com/CS/files/folders/sample_files/entry13316.aspx" target="_blank"&gt;here&lt;/a&gt;.  &lt;p&gt;You can also see it in action here (click on the names and try delete ... I simulated a slight delay for the initial load and the refresh after a delete).   &lt;p&gt;&lt;iframe width="300" height="200" src="http://apps.jeremylikness.com/samples/mvvm-explained/MVVMExampleTestPage.html" border="0"&gt;Click &lt;a href="http://apps.jeremylikness.com/samples/mvvm-explained/MVVMExampleTestPage.html" target="_blank"&gt;here&lt;/a&gt; to view the example in a new window.&lt;/iframe&gt; &lt;p&gt;I think the easiest way to learn the pattern is by seeing a full application being built. I demonstrate this in &lt;a href="http://csharperimage.jeremylikness.com/2010/03/mvvm-with-mef-in-silverlight-video.html" target="_blank"&gt;MVVM with MEF in Silverlight&lt;/a&gt;. In that video, I build some simple viewmodels and show a view that is dynamically swapped based on user selection, and use MEF to wire everything up. A more complex scenario is then introduced in &lt;a href="http://csharperimage.jeremylikness.com/2010/03/mvvm-with-mef-in-silverlight-video_09.html" target="_blank"&gt;Part 2&lt;/a&gt;. &lt;p&gt;So what about those more complicated line of business solutions ... the ones that actually have more than one button, multiple views, and complex logic? That is beyond the scope of this post to cover in detail, but I'd like to tackle a few common scenarios and how I've solved them with MVVM. &lt;p&gt;&lt;b&gt;Common MVVM Scenarios&lt;/b&gt; &lt;p&gt;In my experience, the idea of binding both commands and models or properties is straightforward. It's when you hit specific situations such as showing a dialog box or triggering an animation that MVVM may seem confusing. How do we solve these common problems?  &lt;p&gt;&lt;i&gt;List with Selection&lt;/i&gt; &lt;p&gt;How do you handle a combo box used for selection of a single, or multiple, items with MVVM? It's actually fairly straightforward. In fact, imagine a scenario where you have a combo-box that has a list of contact names, and another view on the same page that shows the contact details when selected. The ViewModel would look something like this, assuming I'm using MEF to wire dependencies (to show you a different way from the reference application): &lt;pre class="brush: csharp;"&gt;public class ContactViewModel : BaseViewModel, IPartImportsSatisfiedNotification
{
    [Import] 
    public IContactService Service { get; set; }

    public ContactViewModel()
    {
       Contacts = new ObservableCollection&amp;lt;Contact&gt;();
    }

    public ObservableCollection&amp;lt;Contact&gt; Contacts { get; set; }

    private Contact _currentContact; 

    public Contact CurrentContact 
    { 
       get { return _currentContact; } 
       set
       {
          _currentContact = value;
          RaisePropertyChanged("CurrentContact"); 
       } 
    }

    public void OnImportsSatisfied() 
    {
       Service.FetchContacts(list =&gt;
          {
             foreach(var contact in list)
             {
                Contacts.Add(contact);
             }
             CurrentContact = Contacts[0];
          });
    }
}
&lt;/pre&gt;&lt;p&gt;In this case, we import a service for getting contacts, wire in the list and set the current contact. The drop down binds to the &lt;code&gt;Contacts&lt;/code&gt; collection. What's important, however, is that the selected item is also bound (this is where the view model maintains state). The binding would look like this:  &lt;pre class="brush: xml;"&gt;...
&amp;lt;ComboBox ItemsSource="{Binding Contacts}" SelectedItem="{Binding CurrentContact,Mode=TwoWay}"/&gt; 
...
&lt;/pre&gt;&lt;p&gt;This ensures whenever something is selected in the list, the current contact is updated. Remember that I mentioned multiple views might share the same viewmodel? In this case, the view for the contact details can use this same view model, and simply bind to the &lt;code&gt;CurrentContact&lt;/code&gt; property. &lt;p&gt;&lt;i&gt;Navigation&lt;/i&gt; &lt;p&gt;Navigation is a common issue to tackle. How do you manage navigation from an MVVM application? Most examples show only a single button or widget on the screen and don't tackle composite applications with multiple pages.  &lt;p&gt;The short answer is that regardless of how you navigate (whether you use your own engine to pull in views, you use the navigation framework supplied by Silverlight, you use region management with Prism or a combination of all of these), you should abstract the mechanism behind an interface. By defining &lt;code&gt;INavigation&lt;/code&gt; or something similar, navigation no longer becomes an MVVM problem. However you solve it, your viewmodel can import INavigation and simply navigate to or trigger the transition as needed. &lt;p&gt;My post on &lt;a href="http://csharperimage.jeremylikness.com/2010/03/mef-instead-of-prism-for-silverlight-3.html" target="_blank"&gt;MEF instead of Prism&lt;/a&gt; shows how to do this with the Managed Extensibility Framework. &lt;a href="http://csharperimage.jeremylikness.com/2010/01/auto-discoverable-views-using-fluent.html" target="_blank"&gt;Auto-discoverable views using a fluent interface&lt;/a&gt; covers mapping views to regions, and &lt;a href="http://csharperimage.jeremylikness.com/2009/11/dynamic-module-loading-with-silverlight.html" target="_blank"&gt;Dynamic module loading with Prism&lt;/a&gt; has a full solution using the navigation framework. &lt;p&gt;&lt;i&gt;Dynamic Modules&lt;/i&gt; &lt;p&gt;This follows navigation. What if you have an extremely large application? It often doesn't make sense to load everything at once. You want the main menu and screne to appear, and then load other modules dynamically as they are needed. This cuts down on the initial time to get the application up and running, and also respects the user's browser and/or desktop memory and CPU.  &lt;p&gt;The issue of dynamic modules isn't really specific to MVVM, but messaging between viewmodels and across modules is of course important. For these, I do believe it makes more sense to look at existing frameworks like MEF and Prism that solve the specific issue. Prism has modules that can be loaded "on demand," and MEF offers a deployment catalog that allows for dynamic loading of XAP files. Prism's solution for messaging across the application is the event aggregator. I talk more about frameworks and solutions for these types of problems in the appendix when I cover existing frameworks that are available to use "out of the box."  &lt;p&gt;&lt;i&gt;Dialog&lt;/i&gt; &lt;p&gt;A common UI pattern is the dialog box (similar to the message box, but expects a reply). I've seen a few people trip over how this can be implemented using both MVVM and the restriction by Silverlight that all code must be asynchronous.  &lt;p&gt;The easiest solution in my opinion is to abstract the dialog behind an interface and provide a callback for the response. The view model can import the dialog, then based on some change in state or a command, trigger the dialog service. The callback will return the response and then the view can process accordingly.  &lt;p&gt;For a fuller explanation, read &lt;a href="http://csharperimage.jeremylikness.com/2010/01/simple-dialog-service-in-silverlight.html" target="_blank"&gt;Simple Dialog Service in Silverlight&lt;/a&gt;.  &lt;p&gt;&lt;i&gt;Animations&lt;/i&gt; &lt;p&gt;This is a very common problem to tackle: how can changes triggered either in the UI or the backend kick off animations and other transitions? &lt;p&gt;There are several solutions to the problem. Here are a few examples of how to solve the problem:  &lt;ul&gt;&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2010/03/introducing-visual-state-aggregator.html" target="_blank"&gt;The Visual State Aggregator&lt;/a&gt; allows you to bind animations based on UI events without involving the viewmodel at all. When you do need to involve it, something like&lt;br /&gt;
&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2010/03/animations-and-view-models.html" target="_blank"&gt;Animation delegates&lt;/a&gt; can do the trick. Want something more abstract? Try&lt;br /&gt;
&lt;li&gt;nRoute's &lt;a href="http://www.orktane.com/Blog/post/2010/01/07/Reverse-ICommands-for-MVVM.aspx" target="_blank"&gt;reverse ICommand&lt;/a&gt; implementation, or&lt;br /&gt;
&lt;li&gt;A sample MVVM framework &lt;a href="http://blogs.infosupport.com/blogs/alexb/archive/2010/04/02/silverlight-4-using-the-visualstatemanager-for-state-animations-with-mvvm.aspx" target="_blank"&gt;that uses the visual state manager&lt;/a&gt;.&lt;/ul&gt;&lt;p&gt;&lt;i&gt;Configuration or Global Values&lt;/i&gt; &lt;p&gt;Another issue I see raised quite often is how to deal with global variables and configuration information. Again, this is less an MVVM problem and more a general architecture consideration. In most cases, you can expose configuration with an interface (&lt;code&gt;IConfiguration&lt;/code&gt;) and then wire up an implementation with your configuration values. Any viewmodel that requires the information simply imports the implementation, whether via MEF, Unity, or some other mechanism, and only one copy of the class is kept (Singleton pattern, although most likely managed by the container and not the class itself).  &lt;p&gt;&lt;i&gt;Asynchronous Processes&lt;/i&gt; &lt;p&gt;One point of confusion with Silverlight is that it forces service calls to be asynchronous. This can seem strange when building a viewmodel: when do you trigger the call, and how do you know it is complete? Typically, this is managed by registered to an event when the process is complete, and binding the results. I prefer to hide the implementation details of the events behind a simple &lt;code&gt;Action&lt;/code&gt; function. Read &lt;a href="http://csharperimage.jeremylikness.com/2009/12/simplifying-asynchronous-calls-in.html" target="_blank"&gt;Simplifying Asynchronous Calls in Silverlight using Action&lt;/a&gt; for an example of this. &lt;p&gt;Sometimes you may have a more complex workflow that requires multiple asynchronous calls to execute and complete prior to continuing. If that is the case, you might want to look into a mechanism for making it easy to code and read the sequential workflow. &lt;a href="http://csharperimage.jeremylikness.com/2010/03/sequential-asynchronous-workflows-part.html" target="_blank"&gt;This post&lt;/a&gt; will help you understand one solution using coroutines, and &lt;a href="http://csharperimage.jeremylikness.com/2010/03/sequential-asynchronous-workflows-in.html" target="_blank"&gt;this post&lt;/a&gt; describes how to use an existing robust framework to manage those calls with thread safety, error handling, and more. &lt;p&gt;&lt;i&gt;Huge Datasets&lt;/i&gt; &lt;p&gt;Finally, I've heard claims that MVVM doesn't handle large datasets well. I would argue it is certain implementations that have this issue, not the pattern itself. The solution is often to page the data, but I find many people approach the problem incorrectly. For some reason, developers want to insist paging is a function of the database and should be isolated to the data access layer. The simple fact that you have a UI element with "current page" and "total pages" suggested it is not just an artifact of the database, but participates in all layers of the application and should be managed as such.  &lt;p&gt;In the most primitive form, you can create a collection that grows as the user pages. If your data is small, you might pull a very large collection and keep it in the Silverlight client, but use a virtualized panel to display the information (the problem with some panels is that they create a control for every bound data element, which can crush performance - virtualized panels only create enough controls to fill the visible window on the screen). &lt;p&gt;Technologies like &lt;a href="http://www.silverlight.net/getstarted/riaservices/" target="_blank"&gt;WCF RIA&lt;/a&gt; support LINQ queries. These queries contain extension methods that allow you to grab only the first few items in a list, rather than fetching the full list at once. The framework also provides helper classes like the &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.data.pagedcollectionview(VS.95).aspx" target="_blank"&gt;PagedCollectionView&lt;/a&gt;&lt;/code&gt; to help filter, sort, and page data. &lt;p&gt;&lt;b&gt;What MVVM &lt;i&gt;Isn't&lt;/i&gt;&lt;/b&gt; &lt;p&gt;No discussion would be complete unless we talked about what MVVM isn't.  &lt;p&gt;MVVM isn't a complete framework. It's a pattern and might be part of a framework, but it's only a piece of the overall solution for your application architecture. It doesn't address, and doesn't really care, about what happens on your server or how your services are put together. It does stress separation of concerns, which is nice. &lt;p&gt;I bet that nowhere in this article did you read a rule that stated, "With MVVM, code behind is not allowed." This is a raging debate but the pattern itself doesn't tell you how to implement your view, whether that is with XAML, code-behind, or a combination of the two. I would suggest that if you are spending days writing something just to avoid minutes of code-behind, your approach is wrong.  &lt;p&gt;It is not required for Silverlight or WPF. I believe that line-of-business, data-driven, and forms-based applications are prime candidates for MVVM. Games, entertainment websites, paint programs, and others may not make sense. Be sure you are using the right tool for the right job.  &lt;p&gt;MVVM is not supposed to slow you down! All new patterns and frameworks come with a learning curve. You'll have to accept that your developers need to learn and understand the pattern, but you should not accept that your entire process suddenly takes longer or becomes delayed. The pattern is useful when it accelerates development, improves stability and performance, reduces risk, and so forth. When it slows development, introduces problems and has your developers cringing whenever they hear the phrase, "design pattern" you might want to rethink your approach. &lt;p&gt;&lt;b&gt;Conclusion&lt;/b&gt; &lt;p&gt;OK, we're done! That's it. I hope you've learned why MVVM is so powerful for Silverlight and WPF applications, what the pattern looks like and even examples of solutions for common problems that MVVM can solve. Now, &lt;a href="#end"&gt;what are your thoughts and comments&lt;/a&gt;? &lt;p&gt;&lt;a href="#appendixa"&gt;Jump to Appendix A: Historical Patterns&lt;/a&gt;  &lt;p&gt;&lt;a href="#appendixb"&gt;Jump to Appendix B: Existing Frameworks&lt;/a&gt; &lt;p&gt;&lt;b&gt;A very special thanks to the community members who took time out of their busy schedules to review and provide preliminary feedback and suggestions for this article:&lt;/b&gt; (in alphabetical order) &lt;ul&gt;&lt;li&gt;Glenn Block (Microsoft Program Manager on .NET FX Team), &lt;a href="http://www.twitter.com/gblock" target="_blank"&gt;@gblock&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/gblock/" target="_blank"&gt;Blog&lt;/a&gt;&lt;br /&gt;
&lt;li&gt;Laurent Bugnion (Silverlight MVP), &lt;a href="http://www.twitter.com/LBugnion" target="_blank"&gt;@LBugnion&lt;/a&gt;, &lt;a href="http://blog.galasoft.ch/" target="_blank"&gt;Blog&lt;/a&gt;&lt;br /&gt;
&lt;li&gt;Corey J Gaudin, &lt;a href="http://www.twitter.com/CoreyGaudin/" target="_blank"&gt;@CoreyGaudin&lt;/a&gt;, &lt;a href="http://acadianaug.org/Article/List/" target="_blank"&gt;Blog&lt;/a&gt;, &lt;a href="http://www.facebook.com/corey.gaudin/" target="_blank"&gt;Facebook&lt;/a&gt;&lt;br /&gt;
&lt;li&gt;Robert Kozak, &lt;a href="http://www.twitter.com/robertkozak" target="_blank"&gt;@RobertKozak&lt;/a&gt;, &lt;a href="http://reflectingcode.blogspot.com/" target="_blank"&gt;Blog&lt;/a&gt;&lt;br /&gt;
&lt;li&gt;Joe McBride, &lt;a href="http://www.twitter.com/xamlcoder/" target="_blank"&gt;@XAMLCoder&lt;/a&gt;, &lt;a href="http://xamlcoder.com/blog/" target="_blank"&gt;Blog&lt;/a&gt;&lt;br /&gt;
&lt;li&gt;Bill Moore, &lt;a href="http://www.twitter.com/codenux" target="_blank"&gt;@CodenUX&lt;/a&gt;, &lt;a href="http://www.codenux.com/" target="_blank"&gt;Website&lt;/a&gt;&lt;br /&gt;
&lt;li&gt;Joost van Schaik, &lt;a href="http://www.twitter.com/localjoost" target="_blank"&gt;@localjoost&lt;/a&gt;, &lt;a href="http://dotnetbyexample.blogspot.com/" target="_blank"&gt;Blog&lt;/a&gt;, &lt;a href="http://www.linkedin.com/in/joostvanschaik/" target="_blank"&gt;LinkedIn&lt;/a&gt;&lt;br /&gt;
&lt;li&gt;Davide Zordan (Silverlight MVP), &lt;a href="http://www.twitter.com/davidezordan" target="_blank"&gt;@DavideZordan&lt;/a&gt;, &lt;a href="http://www.davidezordan.net/blog/" target="_blank"&gt;Blog&lt;/a&gt;&lt;/ul&gt;&lt;a name="appendixa"&gt;&lt;/a&gt; &lt;p&gt;&lt;b&gt;Appendix A: Some Historical Patterns&lt;/b&gt;  &lt;p&gt;&lt;i&gt;Model-View-Controller (MVC)&lt;/i&gt; &lt;p&gt;This software architecture pattern was first described in the context of Smalltalk at Xerox in 1979. If you are interested, you can download some of those original papers (PDF format) by clicking &lt;a href="http://heim.ifi.uio.no/~trygver/2007/MVC_Originals.pdf" target="_blank"&gt;here (PDF)&lt;/a&gt;.  &lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=224&amp;g2_serialNumber=1" alt="Model-View-Controller (MVC)" title="Model-View-Controller (MVC)"/&gt; &lt;p&gt;&lt;i&gt;Model-View-Presenter (MVP)&lt;/i&gt; &lt;p&gt;In 1996, the &lt;a href="http://www.wildcrest.com/Potel/Portfolio/mvp.pdf" target="_blank"&gt;Model-View-Presenter pattern (PDF)&lt;/a&gt; was introduced to the world. This pattern builds on MVC but places special constraints on the controller, now called the presenter. A general overview looks like this:  &lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=239&amp;g2_serialNumber=1" alt="Model-View-Presenter" title="Model-View-Presenter"/&gt; &lt;p&gt;Martin Fowler describes this pattern with two flavors: the &lt;a href="http://www.martinfowler.com/eaaDev/SupervisingPresenter.html" target="_blank"&gt;Supervising Controller/Presenter&lt;/a&gt; and the &lt;a href="http://www.martinfowler.com/eaaDev/PassiveScreen.html" target="_blank"&gt;Passive View&lt;/a&gt;. Here is how Microsoft describes: &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc188690.aspx" target="_blank"&gt;MVP&lt;/a&gt;. &lt;p&gt;&lt;i&gt;Presentation Model&lt;/i&gt; &lt;p&gt;In 2004, Martin Fowler published his description of the &lt;a href="http://martinfowler.com/eaaDev/PresentationModel.html" target="_blank"&gt;Presentation Model&lt;/a&gt;. The summary is quite succinct: "Represent the state and behavior of the presentation independently of the GUI controls used in the interface." As you can see, MVVM is a specialized form of this pattern:  &lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=248&amp;g2_serialNumber=1" alt="Presentation Model" title="Presentation Model"/&gt; &lt;a name="appendixb"&gt;&lt;/a&gt; &lt;p&gt;&lt;b&gt;Appendix B: Pre-existing MVVM Frameworks&lt;/b&gt; &lt;p&gt;Now that we have an idea of what MVVM is all about, you don't have to re-invent the wheel. There are a number of out of the box frameworks that exist which implement MVVM. In no particular order:  &lt;p&gt;&lt;i&gt;&lt;a href="http://mvvmlight.codeplex.com/" target="_blank"&gt;The MVVM Light Toolkit&lt;/a&gt;&lt;/i&gt; &lt;p&gt;This is a very popular toolkit that contains support out of the box for base viewmodels, commands, messaging, and project templates to get started. It supports both WPF and Silverlight projects. &lt;p&gt;&lt;i&gt;&lt;a href="http://projects.nikhilk.net/SilverlightFX" target="_blank"&gt;SilverlightFX&lt;/a&gt;&lt;/i&gt; &lt;p&gt;The stated goals for this framework are to enable concise declarative specification of user interfaces, enable easier separation of view and code, and provide a lean framework. &lt;p&gt;&lt;i&gt;&lt;a href="http://caliburn.codeplex.com/" target="_blank"&gt;Caliburn&lt;/a&gt;&lt;/i&gt; &lt;p&gt;Caliburn is a popular viewmodel-first framework that supports both WPF and Silverlight. More than just MVVM, however, it is a full application framework. &lt;p&gt;&lt;i&gt;&lt;a href="http://cinch.codeplex.com/" target="_blank"&gt;Cinch&lt;/a&gt;&lt;/i&gt; &lt;p&gt;Cinch is a fully featured WPF MVVM framework that makes it easier to develop rich MVVM WPF applications. It also provides UI services/threading/unit tests helpers and much more.&lt;p&gt;&lt;i&gt;&lt;a href="http://nroute.codeplex.com/" target="_blank"&gt;nRoute&lt;/a&gt;&lt;/i&gt; &lt;p&gt;Another MVVM framework, this library is unique for the "reverse commands" that allow binding commands to events in the view as opposed to having the view simply send commands to the viewmodel.  &lt;p&gt;&lt;i&gt;&lt;a href="http://www.paulstovell.com/micromodels-introduction" target="_blank"&gt;MicroModels&lt;/a&gt;&lt;/i&gt; &lt;p&gt;A very lean and lightweight approach to MVVM. &lt;p&gt;&lt;i&gt;&lt;a href="http://compositewpf.codeplex.com/" target="_blank"&gt;Composite WPF/Prism&lt;/a&gt;&lt;/i&gt; &lt;p&gt;Despite the name, this framework supports both WPF and Silverlight. It provides reference MVVM implementations and quickstarts, along with support and guidance for composing applications including commands, event aggregation, region management, and more. &lt;p&gt;While this is certainly not an exhaustive list by any stretch of the imagination, hopefully it gives you an idea of the open source community support available for MVVM and that there are existing mature frameworks that you can choose from to accelerate your development.  &lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt; &lt;a name="end"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-5475991455746376943?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/5475991455746376943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html#comment-form' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/5475991455746376943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/5475991455746376943'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html' title='Model-View-ViewModel (MVVM) Explained'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-3257595057983264378</id><published>2010-08-05T12:45:00.001-04:00</published><updated>2010-08-05T12:46:30.632-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight unit test'/><category scheme='http://www.blogger.com/atom/ns#' term='xaml'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><title type='text'>Unit Testing XAML Data-Bindings in Silverlight</title><content type='html'>&lt;p&gt;In an interview earlier this year with &lt;a href="http://blogs.msdn.com/b/geekspeak/archive/2010/03/01/geekspeak-recording-silverlight-testing-with-jeremy-likness.aspx" target="_blank" title="Silverlight Unit Testing" alt="Silverlight Unit Testing"&gt;MSDN geekSpeak&lt;/a&gt;, I discussed unit testing for Silverlight and some of the frameworks that are available. One audience member raised a very important question: "How do we test the XAML?" Specifically, what happens when we hand off XAML to a designer or another developer, and they accidently remove a data-binding or other critical element, then pass it back to us?&lt;br /&gt;
&lt;p&gt;&lt;b&gt;The Problem&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;Many developers don't realize this, but the view is not decoupled from the underlying code. Unless you are using a &lt;a href="http://csharperimage.jeremylikness.com/2010/05/mvvm-coding-by-convention-convention.html" target="_blank"&gt;convention-based approach&lt;/a&gt; (and then an affinity still exists, albeit expressed via the convention), you are likely either wiring in events and managing the view from code-behind, or using data-binding to bind a view to an underlying view model or binding model. One mistake people tend to make is the assumption that the view is completely decoupled from the view model.&lt;br /&gt;
&lt;p&gt;The truth is, the data-bindings are a double-edged sword. First, make no mistake, you are explicitly referring to a contract when you specify data-binding. You might not need to know the specific type of the underlying data context, but you are pointing to specific sources and property paths on "some object" that must be satisfied. The "double-edge" is that the data-binding framework will silently swallow any exceptions if you happen to bind to the wrong path. Fat-finger "country" as "county" and you may find a big blank label appearing where you were hoping to see "United States." &lt;br /&gt;
&lt;p&gt;Even more likely is the fact that often you may have a &lt;i&gt;designer&lt;/i&gt; creating XAML assets, an &lt;i&gt;integrator&lt;/i&gt; moving those assets into the project and then a &lt;i&gt;developer&lt;/i&gt; working on the actual code. At any phase of the hand-off, someone might get fancy and decide to replace a combo box with a list box and forget to update the data-bindings. The compiler won't complain at all, because there is no check for the &lt;i&gt;absence&lt;/i&gt; of data-binding, so you'll likely not catch the error until you begin testing the application.&lt;br /&gt;
&lt;p&gt;&lt;b&gt;The Solution&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;While there is no easy way to "type" the view and force the compiler to emit errors when the data-binding is incorrect, you can create unit tests on those views to test the expected bindings. You can also test for attached behaviors and other artifacts in the XAML that are expected for the application to run successfully.&lt;br /&gt;
&lt;p&gt;Let's take a look at a simple view model I like to use when demonstrating the &lt;a href="http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html" target="_blank"&gt;Model-View-ViewModel (MVVM)&lt;/a&gt; pattern. I call it &lt;code&gt;Cascadia&lt;/code&gt; because it facilitates the classic case of cascading dropdowns. The view model sits on top of a service for fetching countries and states or provinces, that is injected via the Managed Extensibility Framework. MEF is outside the scope of this post, and we won't need it for testing anyway because we'll mock the dependencies. Here is my view model: &lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;[Export]
public class CascadiaViewModel : INotifyPropertyChanged, IPartImportsSatisfiedNotification 
{
    [Import]
    public IAddressService AddressService { get; set; }

    public CascadiaViewModel()
    {
        Countries = new ObservableCollection&amp;lt;Country&gt;();
        States = new ObservableCollection&amp;lt;State&gt;();

        if (!DesignerProperties.IsInDesignTool) return;

        // design-time controls

        var country = new Country {CountryCode = "US", CountryName = "United States"};
        var state = new State {StateCode = "GA", StateName = "Georgia", StateCountry = country};
        Countries.Add(country);
        States.Add(state);
        CurrentCountry = country;
        CurrentState = state;
    }

    public ObservableCollection&amp;lt;Country&gt; Countries { get; set; }

    private Country _country;

    public Country CurrentCountry
    {
        get { return _country; }
        set
        {
            _country = value;
            _UpdateStates();
            _RaisePropertyChanged("CurrentCountry");
        }
    }

    private void _UpdateStates()
    {
        if (DesignerProperties.IsInDesignTool)
        {
            return;
        }

        States.Clear();
        AddressService.GetStatesForCountry(CurrentCountry.CountryCode, states=&gt;
           {
              foreach(var state in states)              
              { States.Add(state); }
              CurrentState = States[0];
           });
    }

    public ObservableCollection&amp;lt;State&gt; States { get; set; }

    private State _state;

    public State CurrentState
    {
        get { return _state; }
        set
        {
            _state = value;
            _RaisePropertyChanged("CurrentState");
        }
    }

    private void _RaisePropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnImportsSatisfied()
    {
        AddressService.GetCountries(countries =&gt;
        {
            foreach (var country in countries)
            {
                Countries.Add(country);
            }
            CurrentCountry = Countries[0];
        });
    }
}
&lt;/pre&gt;&lt;p&gt;Notice that I am providing some design-time support right in the view model so it will appear in the designer when a view is databound. There may be some arguments about the concept of a "designer" leaking into my view model, but in my opinion, the view model is specific to views. It is not "business logic" but an entity responsible for coordinating the hand-off between underlying business logic and the view itself. Therefore, why not have the intelligence to provide some sample data during design time?&lt;br /&gt;
&lt;p&gt;The behavior is straightforward. We populate a list of countries, synchronize a default country, then populate a list of states for the selected country and synchronize a default state. The expected behavior is that I can change the selected state, and when I change the selected country, my state list is refreshed and a new default picked. All of this can be tested before we even worry about the service or the view, in my opinion one of the advantages of the MVVM pattern.&lt;br /&gt;
&lt;p&gt;Next, let's take a look at the XAML for a view that binds to the view model. Here is the markup:&lt;br /&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;UserControl x:Uid="UserControl_1" x:Class="Cascadia.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc:Ignorable="d" 
   d:DesignHeight="300" 
   d:DesignWidth="400"&gt;
  &amp;lt;Grid x:Uid="LayoutRoot" x:Name="LayoutRoot" 
      Background="White" DataContext="{Binding Source={StaticResource VMLocator},Path=Cascadia}"&gt;
    &amp;lt;Grid.ColumnDefinitions&gt;
      &amp;lt;ColumnDefinition x:Uid="ColumnDefinition_1" Width="Auto" /&gt;
      &amp;lt;ColumnDefinition x:Uid="ColumnDefinition_2" Width="Auto" /&gt;
    &amp;lt;/Grid.ColumnDefinitions&gt;
    &amp;lt;Grid.RowDefinitions&gt;
      &amp;lt;RowDefinition x:Uid="RowDefinition_1" Height="Auto" /&gt;
      &amp;lt;RowDefinition x:Uid="RowDefinition_2" Height="Auto" /&gt;
      &amp;lt;RowDefinition x:Uid="RowDefinition_3" Height="Auto" /&gt;
      &amp;lt;RowDefinition x:Uid="RowDefinition_4" Height="Auto" /&gt;
    &amp;lt;/Grid.RowDefinitions&gt;
    &amp;lt;TextBlock x:Uid="TextBlock_1" Text="Select Your Country:" Grid.Row="0" Grid.Column="0" AutomationProperties.AutomationId="TextBlock_1" /&gt;
    &amp;lt;ComboBox x:Uid="cbCountries" x:Name="cbCountries" Grid.Row="0" Grid.Column="1" ItemsSource="{Binding Countries}" SelectedItem="{Binding CurrentCountry,Mode=TwoWay}" DisplayMemberPath="CountryName" /&gt;
    &amp;lt;TextBlock x:Uid="TextBlock_2" Text="Select Your State:" Grid.Row="1" Grid.Column="0" AutomationProperties.AutomationId="TextBlock_2" /&gt;
    &amp;lt;ComboBox x:Uid="cbStates" x:Name="cbStates" ItemsSource="{Binding States}" SelectedItem="{Binding CurrentState,Mode=TwoWay}" Grid.Row="1" Grid.Column="1" DisplayMemberPath="StateName" /&gt;
    &amp;lt;TextBlock x:Uid="TextBlock_3" Text="Selected Country:" Grid.Row="2" Grid.Column="0" AutomationProperties.AutomationId="TextBlock_3" /&gt;
    &amp;lt;TextBlock x:Uid="tbSelectedCountry" x:Name="tbSelectedCountry" Text="{Binding Path=CurrentCountry.CountryName}" Grid.Row="2" Grid.Column="1" Height="16" VerticalAlignment="Bottom" /&gt;
    &amp;lt;TextBlock x:Uid="TextBlock_4" Text="Selected State:" Grid.Row="3" Grid.Column="0" AutomationProperties.AutomationId="TextBlock_4" /&gt;
    &amp;lt;TextBlock x:Uid="tbSelectedState" x:Name="tbSelectedState" Text="{Binding Path=CurrentState.StateName}" Grid.Row="3" Grid.Column="1" /&gt;
  &amp;lt;/Grid&gt;
&amp;lt;/UserControl&gt;
&lt;/pre&gt;&lt;p&gt;This basically shows two drop-downs, with two labels that synchronize with the selected items. The "affinity" or "coupling" is introduced when we specify a data-binding path and expected something specific, such as &lt;code&gt;CurrentState.StateName&lt;/code&gt;, to be present and correct. Our application is not functioning correctly if these bindings don't work. &lt;br /&gt;
&lt;p&gt;If you're wondering about the &lt;code&gt;Uid&lt;/code&gt; and &lt;code&gt;AutomationProperties&lt;/code&gt;, both are important for globalization/localization as well as accessibility. In fact, I'm excited to be on one of the teams that is previewing UI Automation for Silverlight. This allows recording and/or creating coded UI tests (similar to WPF) and running/testing those against Silverlight applications. I've been very pleased with what the tool can do so far and am excited about the upcoming release to the public (this is not the same as the "manual" automation that &lt;a href="http://csharperimage.jeremylikness.com/2010/07/silverlight-ui-automation-testing-using.html" target="_blank" title="Silverlight UI Automation"&gt;I blogged about here&lt;/a&gt;.) &lt;br /&gt;
&lt;p&gt;&lt;b&gt;The Test&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;Now we can get down to writing a test to ensure that the bindings are working properly. In &lt;a href="http://www.amazon.com/Art-Unit-Testing-Examples-Net/dp/1933988274/" target="_blank"&gt;The Art of Unit Testing&lt;/a&gt; author Roy Osherove lists several properties of a good unit test. Two of those include &lt;i&gt;it should run at the push of a button&lt;/i&gt; and &lt;i&gt;it should run quickly&lt;/i&gt;. In this case, the workflow is that we receive XAML from a designer or integrator. Upon checkin, either we have an automated build process that runs our unit tests automatically, or we pull it down and as a manual process set the test page as the startup page and hit F5 to run the tests. Either way, we can check very quickly whether or not our bindings were preserved.&lt;br /&gt;
&lt;p&gt;What does a test look like? In the setup for our test, we'll mock out the service and specify the countries and states we want. I'll also override the view locator specified in XAML and directly bind to the view model for our test. This is the test initialize method:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;private MainPage _target;
private CascadiaViewModel _viewModel;
private Mock&amp;lt;IAddressService&gt; _service;

private Country[] _countries;
private State[] _states;

[TestInitialize]
public void TestInit()
{
    var us = new Country {CountryCode = "US", CountryName = "United States"};
    var georgia = new State {StateCode = "GA", StateCountry = us, StateName = "Georgia"};
    var mexico = new Country {CountryCode = "MX", CountryName = "Mexico"};
    var oaxaca = new State {StateCode = "OA", StateCountry = mexico, StateName = "Oaxaca"};

    _target = new MainPage();

    _countries = new[] {us, mexico};
    _states = new[] {georgia, oaxaca};

    _viewModel = new CascadiaViewModel();

    _service = new Mock&amp;lt;IAddressService&gt;();
    _viewModel.AddressService = _service.Object;

    _service.Setup(s =&gt; s.GetCountries(It.IsAny&amp;lt;Action&amp;lt;IEnumerable&amp;lt;Country&gt;&gt;&gt;()))
        .Callback((Action&amp;lt;IEnumerable&amp;lt;Country&gt;&gt; action) =&gt; action(_countries));

    _service.Setup(s =&gt; s.GetStatesForCountry(It.IsAny&amp;lt;string&gt;(), It.IsAny&amp;lt;Action&amp;lt;IEnumerable&amp;lt;State&gt;&gt;&gt;()))
        .Callback(
            (string countryCode, Action&amp;lt;IEnumerable&amp;lt;State&gt;&gt; action) =&gt;
            action(from s in _states where s.StateCountry.CountryCode.Equals(countryCode) select s));

    GetUiElement&amp;lt;Grid&gt;("LayoutRoot").DataContext = _viewModel;
}

private T GetUiElement&amp;lt;T&gt;(string name) where T : UIElement
{
    return (T) _target.FindName(name);
}
&lt;/pre&gt;&lt;p&gt;Notice at this point we are just setting up the mocks and data-binding the view model. Next, we'll test the actual bindings: &lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;[Asynchronous]
[TestMethod]
public void TestCountrySelection_UpdatesViewModelAndDataBindings()
{
    _target.Loaded +=
        (o, e) =&gt;
            {
                _viewModel.OnImportsSatisfied(); // set this up

                var comboBox = GetUiElement&amp;lt;ComboBox&gt;("cbCountries");
                var stateComboBox = GetUiElement&amp;lt;ComboBox&gt;("cbStates");
                var textBlock =
                    GetUiElement&amp;lt;TextBlock&gt;("tbSelectedCountry");
                var stateTextBlock =
                    GetUiElement&amp;lt;TextBlock&gt;("tbSelectedState");


                var defaultStates = from s in _states
                                    where
                                        s.StateCountry.CountryCode.Equals(
                                            _countries[0].CountryCode)
                                    select s;

                // defaults
                Assert.AreEqual(_countries[0], _viewModel.CurrentCountry,
                                "Country combo box failed to initialize current country.");
                Assert.AreEqual(_countries[0].CountryName, textBlock.Text,
                                "Country combo box failed to initialize the text block.");
                Assert.AreEqual(_states[0], _viewModel.CurrentState,
                                "Failed to initialize current state.");
                Assert.AreEqual(_states[0].StateName, stateTextBlock.Text,
                                "Failed to initialize the state text block.");

                CollectionAssert.AreEquivalent(comboBox.Items, _countries,
                                                "Failed to data-bind countries.");
                CollectionAssert.AreEquivalent(stateComboBox.Items,
                                                defaultStates.ToArray(),
                                                "Failed to data-bind states.");
                        
                comboBox.SelectedItem = _countries[1];

                var mexicoStates = from s in _states
                                    where
                                        s.StateCountry.CountryCode.Equals(
                                            _countries[1].CountryCode)
                                    select s;

                // defaults
                Assert.AreEqual(_countries[1], _viewModel.CurrentCountry,
                                "Country combo box failed to update current country.");
                Assert.AreEqual(_countries[1].CountryName, textBlock.Text,
                                "Country combo box failed to update the text block.");
                Assert.AreEqual(_states[1], _viewModel.CurrentState,
                                "Failed to update current state.");
                Assert.AreEqual(_states[1].StateName, stateTextBlock.Text,
                                "Failed to update the state text block.");

                CollectionAssert.AreEquivalent(stateComboBox.Items,
                                                mexicoStates.ToArray(),
                                                "Failed to update data-binding for states.");

                EnqueueTestComplete();
            };

    TestPanel.Children.Add(_target);
}
&lt;/pre&gt;&lt;p&gt;We are doing a few things here. Unit tests follow the pattern: &lt;i&gt;arrange, act, assert&lt;/i&gt;. I am arranging the view model and services in the beginning. Note that we wait until the target view is loaded before acting on it, so that data-binding has a chance to take effect. We are placing the view on a test surface, but tools like &lt;a href="http://statlight.codeplex.com/" target="_blank"&gt;StatLight&lt;/a&gt; can effectively mock the surface to allow the tests to be run offline in an automated fashion. The test is asynchronous because we must wait for the loaded event to fire before acting and asserting, and the last step we do is add the view to the test surface.&lt;br /&gt;
&lt;p&gt;When the view is loaded, I'm first testing some pre-conditions. These are the default bindings we'd expect from the view model being initialized. Then, I change the selection and assert that the changes happened as expected.&lt;br /&gt;
&lt;p&gt;This test will function on several levels. First, because I'm grabbing controls by name, if the names change (for example, we change a combo box to a list box and change the name to "lbCountries") then the test will fail. If I don't have an affinity for named controls (i.e. everything happens through databinding) then I will change my strategy to use the automation id. I'll call the control something generic like "CountryList" and will find it regardless of the control type or name.&lt;br /&gt;
&lt;p&gt;Second, we have some very specific behaviors we expect, such as changing a country and having the state list and default state update as well. This is fully tested and if any of the data-bindings are broken, the test will fail. I can quickly determine if the XAML was corrupted and fix the problem before it gets into production. I think most developers will agree that the easiest way to fix a bug is to find it as close to the source as possible.&lt;br /&gt;
&lt;p&gt;What if I needed to test a custom control, or even do something simple like emulate a button click to test data-binding to an &lt;code&gt;ICommand&lt;/code&gt; object? No problem. This is where we would use automation peers. For example, to simulate a button click, I can include the following code: &lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;var btn = GetUiElement&amp;lt;Button&gt;("btnCommand");
var btnPeer = new ButtonAutomationPeer(btn);
btnPeer.Click();
&lt;/pre&gt;&lt;p&gt;The above code will simulate a button click, and then I can test my command to ensure it fired correctly. For custom controls, you can &lt;a href="http://blogs.msdn.com/b/gisenberg/archive/2008/07/12/ui-automation-in-silverlight-simulating-user-interactions.aspx" target="_blank"&gt;provide your own automation peer&lt;/a&gt;, which is a good idea anyway for accessibility.&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;
&lt;p&gt;Hopefully this article demonstrated another way to catch issues fast, close to the source and before the code even makes it to your QA machine. Indirectly, I've shown how MVVM can improve the development process through both testability and workflow (i.e. being able to work on independent pieces, including XAML and view logic, separately). You also witnessed how unit testing provides value to the development process and why most of the time the net impact is faster time to "production ready" in spite of the overhead of writing tests.&lt;br /&gt;
&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-3257595057983264378?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/3257595057983264378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/unit-testing-xaml-data-bindings-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/3257595057983264378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/3257595057983264378'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/unit-testing-xaml-data-bindings-in.html' title='Unit Testing XAML Data-Bindings in Silverlight'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-6691055103562793171</id><published>2010-08-03T17:08:00.003-04:00</published><updated>2010-08-03T21:31:45.691-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='silverlight unit test'/><category scheme='http://www.blogger.com/atom/ns#' term='rx'/><category scheme='http://www.blogger.com/atom/ns#' term='reactive extensions'/><title type='text'>Using Reactive Extensions (Rx) to Simplify Asynchronous Tests</title><content type='html'>&lt;a href="http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx" target="_blank"&gt;Reactive Extensions (Rx)&lt;/a&gt; is a product from Microsoft Research that simplifies the management and composition of asynchronous events. If you read my earlier post on &lt;a href="http://csharperimage.jeremylikness.com/2010/03/sequential-asynchronous-workflows-in.html" target="_blank"&gt;Asynchronous Workflows&lt;/a&gt;, you'll understand why the asynchronous programming model can sometimes lead to confusing and hard-to-maintain code. &lt;br /&gt;
&lt;br /&gt;
There is nothing wrong with the model, but the fact that you must subscribe to an event or register a callback means your code can end up nested and scattered to the winds. Add to that the complexity of aggregating events (for example, firing multiple asynchronous events and then waiting for them all to complete before going on) and it's enough to require a visit to the pharmacy. OK, that was a bad lead-in because of course that's where you can get your Rx (prescription). &lt;br /&gt;
&lt;br /&gt;
There is a lot to explore in the framework, but you can start by visiting the main site and downloading the extensions (they are available for .NET 3.5, .NET 4.0, Silverlight 3, Silverlight 4 and JavaScript). Probably the best and easiest way to learn using Rx is to follow the hands-on labs that you can download in PDF format from &lt;a href="http://blogs.msdn.com/b/rxteam/archive/2010/07/15/rx-hands-on-labs-published.aspx" target="_blank"&gt;this blog post&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I'd like to give a gentle introduction by demonstrating how it solved a very specific need of mine. A very common pattern is what I'll call "synchronized lists" where one list triggers a change in the other. The classic example is selecting a country to get a list of states for that country. Selecting a country means we fetch or filter a new list of states, and if we're kind to the end user we'll also give them a default (either a state or perhaps a "select one" prompt). One test would be changing the country and validating that the list of states updated correctly. Another test, important for data-binding, is to ensure that setting the country raises both the country and the state property changed events. If someone were to come along and change the setter to the private property, the property change notification would fail to fire and we'd lose our data-binding. &lt;br /&gt;
&lt;br /&gt;
To test is straightforward: set up the view model, register to the event, then listen and confirm we get the properties we are looking for. Implementing it is another story. The original syntax would involve registering a lambda that adds to a list, then waiting for a particular time (to make sure all events have fired) and then check the list. There is no "clean" way to do it without timers or a counter or making assumptions about the order the properties may come in.&lt;br /&gt;
&lt;br /&gt;
The Reactive Extensions simplify this tremendously. Take a look at the following code: &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public void TestChangeCurrentCountry_RaisesPropertyChanged()
{
    var properties = new List&amp;lt;string&amp;gt;();
    var expected = new[] {"CurrentCountry", "CurrentState"};

    // set it up
    _target.OnImportsSatisfied();

    var propertyChanged = (from evt 
      in Observable.FromEvent&amp;lt;PropertyChangedEventArgs&amp;gt;(_target, "PropertyChanged")
      select evt.EventArgs.PropertyName).Take(2);
                
    using (propertyChanged.Subscribe(
      properties.Add,
      ex =&amp;gt; Assert.Fail(ex.Message),
      () =&amp;gt;
         {                                                 
            CollectionAssert.AreEquivalent(expected, properties,
            "Invalid properties were raised on the notify change event.");
            EnqueueTestComplete();
         }))
    {
        _target.CurrentCountry = _countries[1];
    }
}
&lt;/pre&gt;&lt;br /&gt;
What's going on here? I set up a list to grab properties as they are raised, and I&amp;nbsp;initialize a&amp;nbsp;list of expected properties. This makes the conditions of the test very clear. I'm using MEF, so what happens in unit tests is that I set up the view model with a bunch of mock objects to return my data: i.e. "if you ask for a country, I'll give you this" and so forth. I explicitly call "OnImportsSatisfied" to simulate what would happen if I were actually composing the view model with MEF (in this case, however, my test is composing it).&lt;br /&gt;
&lt;br /&gt;
In this case, the view model will call the country service to populate the list, then the state service, and set defaults. All of these are fed based on the mock configurations.&lt;br /&gt;
&lt;br /&gt;
Once we have the view model prepared, the Rx steps in. I set up an observable collection that is based on the property changed event. Notice we pass the expected &lt;code&gt;EventArgs&lt;/code&gt;, the object to inspect and the event to listen for. The power of Rx is that it will asynchronously build the list for me as the event is raised, in this case returning the property names (because of my select statement). I am only expecting 2, so I can use the standard LINQ "Take(2)" for the list to stop after the second property changed event (otherwise, it would continue listening and building out the list &lt;em&gt;ad infinitum&lt;/em&gt;). &lt;br /&gt;
&lt;br /&gt;
The using statement provides an action as items are added (note I'm using a &lt;a href="http://msdn.microsoft.com/en-us/library/aa691356(VS.71).aspx" target="_blank"&gt;method group&lt;/a&gt; to specify that the string is passed to the add method of the properties list.) If an exception is thrown, I'll fail the test gracefully with an assert. The last parameter is the action to perform when complete, which is after both properties have been added. Here, I compare the two lists and let the Silverlight Unit Testing Framework know that the test is complete.&lt;br /&gt;
&lt;br /&gt;
The entire statement wraps the functionality I'll use to trigger the behaviors - in this case, changing the country to set off the property change notification. &lt;br /&gt;
&lt;br /&gt;
While this is a very simple example, I encourage you to download the hands on labs to see more complex examples that compose multiple asynchronous events together in a single collection. It's a powerful framework that deserves a close look!&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img alt="Jeremy Likness" border="0" src="http://jeremylikness.com/signature.gif" title="Jeremy Likness" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-6691055103562793171?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/6691055103562793171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/using-reactive-extnesions-rx-to.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/6691055103562793171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/6691055103562793171'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/08/using-reactive-extnesions-rx-to.html' title='Using Reactive Extensions (Rx) to Simplify Asynchronous Tests'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-8849764732324090917</id><published>2010-07-26T18:50:00.001-04:00</published><updated>2010-07-26T18:51:44.792-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='automated testing'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='ui automation'/><category scheme='http://www.blogger.com/atom/ns#' term='prism'/><title type='text'>Silverlight UI Automation Testing using Prism 4.0</title><content type='html'>&lt;p&gt;One popular gripe about Silverlight has been the lack of integrated testing tools. There are several types of tests you may perform against a software project. Unit tests can be performed with the aid of the &lt;a href="http://code.msdn.microsoft.com/silverlightut" target="_blank"&gt;Silverlight Unit Testing Framework&lt;/a&gt; and automated with a third-party tool such as &lt;a href="http://statlight.codeplex.com/" target="_blank"&gt;StatLight&lt;/a&gt;.

&lt;p&gt;Automation testing involves hosting the actual Silverlight application in a browser and performing a walkthrough based on a script. Typically, this script will follow a "happy path" through the application, but more detailed automation tests check for known error conditions as well. The automation tests simulate entering text, clicking buttons, and scanning results.

&lt;p&gt;Silverlight automation testing is possible, and has been for some time, but it is far easier to do with some helper projects supplied by the &lt;a href="http://compositewpf.codeplex.com/" target="_blank"&gt;Prism team&lt;/a&gt;. If you are interested in running actual tests within the Visual Studio IDE, this post will provide step-by-step instructions to get you where you need to be.

&lt;p&gt;Please take the time to go through this step-by-step if you are serious about automation testing. There are lots of small pieces that may seem complex at first, but once you've walked through the steps, it should be fairly straightforward and easy for you to set up new projects and automate the testing to a greater extent than shown here.

&lt;p&gt;&lt;b&gt;Get to Know Your Peers&lt;/b&gt;

&lt;p&gt;The automation testing is performed with the help of &lt;a href="http://msdn.microsoft.com/en-us/library/cc645045(VS.95).aspx" target="_blank"&gt;Automation Peers&lt;/a&gt;, a feature that has been around for Silverlight since at least 2.0. Automation peers provide a consistent interface for interacting with controls. They have a very practical use for &lt;a href="http://www.code-magazine.com/article.aspx?quickid=0810062&amp;amp;page=1" target="_blank"&gt;accessibility&lt;/a&gt; (that article shows how long it's been around — so why do so many people ignore it?) While the base controls supplied by Silverlight have their own peers, you'll need to learn how to create &lt;a href="http://blogs.msdn.com/b/gisenberg/archive/2008/07/12/ui-automation-in-silverlight-simulating-user-interactions.aspx" target="_blank"&gt;your own custom automation peers&lt;/a&gt; if you wish to automate the testing of custom controls.

&lt;p&gt;&lt;b&gt;Grab the Latest Prism Drop&lt;/b&gt;

&lt;p&gt;Now we need to get Prism. The latest drop as of this writing is &lt;a href="http://compositewpf.codeplex.com/releases/view/48920" target="_blank"&gt;Drop 4&lt;/a&gt; but they are releasing fast and furious and should have the full release out by by winter of 2010. (Keep in mind this blog post may quickly become obsolete, as Microsoft is working on a &lt;a href="http://blogs.msdn.com/b/anutthara/archive/2010/07/14/update-on-silverlight-ui-automation-release.aspx" target="_blank"&gt;native solution&lt;/a&gt; for this).

&lt;p&gt;OK, you've grabbed it and installed it? Great, let's get going. I'm not going to provide a completed project for this because everything you need - all source code and steps - are included in this post.

&lt;p&gt;&lt;b&gt;Create a Simple Project&lt;/b&gt;

&lt;p&gt;Let's create a very simple project to get started. What we'll do is create two text boxes and a button. When you enter text in the first box and click the button, it should get updated to the other box. Easy enough, but then we'll automate the tests to ensure the update is happening.

&lt;p&gt;Create a new Silverlight application.

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=288&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;Give it a name &lt;code&gt;UIAutomation&lt;/code&gt; and include a solution (check the option to create a directory) &lt;code&gt;UIAutomationSln&lt;/code&gt; (or whatever your naming preference is).

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=290&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;Host it in a web application, and make sure the version is Silverlight 4.

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=292&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;Now we'll add a simple set of controls. Set the grid to three columns, then add two text boxes and one button. The XAML looks like this (be sure to key in the &lt;code&gt;Click&lt;/code&gt; attribute so it auto-generates the code-behind handler).
&lt;pre class="brush: xml;"&gt;
   &amp;lt;Grid x:Name="LayoutRoot" Background="White"&gt;

        &amp;lt;Grid.ColumnDefinitions&gt;

            &amp;lt;ColumnDefinition/&gt;

            &amp;lt;ColumnDefinition/&gt;

            &amp;lt;ColumnDefinition/&gt;

        &amp;lt;/Grid.ColumnDefinitions&gt;

        &amp;lt;TextBox x:Name="txtSource" Grid.Column="0"/&gt;

        &amp;lt;TextBox x:Name="txtTarget" Grid.Column="2"/&gt;

        &amp;lt;Button x:Name="btnSubmit" Content=" GO " Grid.Column="1" Click="btnSubmit_Click"/&gt;

    &amp;lt;/Grid&gt;

&lt;/pre&gt;

&lt;p&gt;In the code-behind, handle the click event and move the source text to the target:
&lt;pre class="brush: csharp;"&gt;
using System.Windows;



namespace UIAutomation

{

    public partial class MainPage

    {

        public MainPage()

        {

            InitializeComponent();

        }



        private void btnSubmit_Click(object sender, RoutedEventArgs e)

        {

            txtTarget.Text = txtSource.Text;

        }

    }

}

&lt;/pre&gt;

&lt;p&gt;At this point, you can hit F5 and run it to see it does what we want.

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=294&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;&lt;b&gt;Preparing for Automation&lt;/b&gt;

&lt;p&gt;Right now, we need to do one small thing to prepare the controls for automation. Instead of building a custom automation peer, we're going to take advantage of some built-in Silverlight functionality that exposes automation for us. First, we'll simply define some automation-specific identifiers for the controls. Open up the XAML for the main page and add the automation properties you see below:

&lt;p&gt;&lt;img alt="UI Automation Identifiers for Silverlight" src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=296&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;As you can see, these do not have to be the same as the names of the controls. These identifiers consistently expose the controls to the automation system. Now we're ready to test it!

&lt;p&gt;&lt;b&gt;Add the Prism Acceptance Test Library&lt;/b&gt;

&lt;p&gt;We're going to add a library from Prism that will help with the test automation. To do so, you'll need to right-click on the solution, and choose "add ... existing project."

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=298&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;Navigate to the Prism acceptance test library, and select the project file.

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=300&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;&lt;b&gt;Add the Test Project&lt;/b&gt;

&lt;p&gt;Now, we'll add a test project. This project is a regular Visual Studio Test Project, &lt;i&gt;not&lt;/i&gt; a Silverlight test project. Call the project &lt;code&gt;UIAutomation.Test&lt;/code&gt;.

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=302&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;Next, we'll need to add a few references. First, add the reference to the acceptance test library to the newly added test project. Right click on references, choose "add reference" and select the acceptance test library from the "Projects" tab.

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=304&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;Finally, go into the same dialog, but this time add the UI automation references from the &lt;code&gt;.NET&lt;/code&gt; tab:

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=306&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;&lt;b&gt;Add your Control Resources&lt;/b&gt;

&lt;p&gt;The Prism acceptance test library is designed to be used with projects that share code between Silverlight and WPF. For this reason, a special resource file is used to map between the project types and the automation identifiers for the controls. We'll go ahead and build our own resource dictionary to map the controls. Anything in Silverlight should end with a &lt;code&gt;_Silverlight&lt;/code&gt; prefix.

&lt;p&gt;Create a folder called "TestData" in the test project, and add a resource file called "Controls":

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=308&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;In the resource dictionary, fill out the mapping for the control names to the automation identifiers that we added earlier. Notice by convention, we're using the control id, followed by the Silverlight designation, for the key, then putting the automation id as the value.

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=310&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;Because the test class must use this resource file, we want to make sure it gets copied to the output directory. There are two things we'll need to do. I'll cover the second step later. The first step is to make sure the resource is set to "copy always". Simply select the resource file, go into properties, and set the copy attribute:

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=312&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;&lt;b&gt;Add the Application Configuration&lt;/b&gt;

&lt;p&gt;The acceptance test library drives from a configuration file that you place in the test project. Right click on the test project and choose "add new item." Select "Application Configuration File" and keep the default, then click "Add." This will add an &lt;code&gt;App.config&lt;/code&gt; file to the root of your test project. Open this file up, and paste the following:
&lt;pre class="brush: xml;"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8" ?&gt;

&amp;lt;configuration&gt;

  &amp;lt;configSections&gt;

    &amp;lt;sectionGroup name="BrowserSupport"&gt;

      &amp;lt;section name="Browsers" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null" /&gt;

    &amp;lt;/sectionGroup&gt;

  &amp;lt;/configSections&gt;



  &amp;lt;appSettings&gt;

   

    &amp;lt;!-- Browser Path and process parameters --&gt;

    &amp;lt;add key="IEPartialPath" value="\\Internet Explorer\\iexplore.exe"/&gt;

    &amp;lt;add key="FirefoxPartialPath" value="\\Mozilla Firefox\firefox.exe"/&gt;

    &amp;lt;add key="SafariPartialPath" value="\\Safari\Safari.exe"/&gt;

    &amp;lt;add key="IEAppProcessName" value="iexplore"/&gt;

    &amp;lt;add key="FirefoxAppProcessName" value="firefox"/&gt;

    &amp;lt;add key="SafariAppProcessName" value="Safari"/&gt;



    &amp;lt;!-- Time to wait for the application to be launched --&gt;

    &amp;lt;add key="ApplicationLoadWaitTime" value="60000"/&gt;



    &amp;lt;!-- Test Data config files --&gt;

    &amp;lt;!--&amp;lt;add key="TestDataInputFile" value=".\TestData\TestDataInput.resx"/&gt;--&gt;

    &amp;lt;add key="ControlIdentifiersFile" value=".\TestData\Controls.resx"/&gt;

  &amp;lt;/appSettings&gt;



  &amp;lt;!-- Config section for Cross-Browser support --&gt;

  &amp;lt;BrowserSupport&gt;

    &amp;lt;Browsers&gt;



      &amp;lt;add key ="InternetExplorer" value ="AcceptanceTestLibrary.Common.CrossBrowserSupport.InternetExplorerLauncher" /&gt;

      &amp;lt;!--&amp;lt;add key="FireFox" value="AcceptanceTestLibrary.Common.CrossBrowserSupport.FirefoxLauncher" /&gt;

      &amp;lt;add key="Safari" value="AcceptanceTestLibrary.Common.CrossBrowserSupport.SafariLauncher" /&gt;--&gt;

    &amp;lt;/Browsers&gt;

  &amp;lt;/BrowserSupport&gt;



&amp;lt;/configuration&gt;

&lt;/pre&gt;

&lt;p&gt;Note that we've done the bare minimum to set up an Internet Explorer launch and pointed to the controls resource we created. You can obviously tinker with these settings and include other browsers as part of the test. The Prism example has more in the application settings, such as the path to the application and some other settings, but these are the key ones for the application to work.

&lt;p&gt;&lt;b&gt;Set up a Base Automation Helper&lt;/b&gt;

&lt;p&gt;We're not quite ready for the test class. To make it easy to access our automation peers, we can build a base class that exposes the properties we need. This will help us abstract access to the controls for our tests.

&lt;p&gt;In the test project, add a new C# class called &lt;code&gt;MainPageBase.cs&lt;/code&gt;. Populate it with the following code:
&lt;pre class="brush: csharp;"&gt;
using System.Windows.Automation;

using AcceptanceTestLibrary.Common;

using AcceptanceTestLibrary.TestEntityBase;



namespace UIAutomation.Test

{

    public static class MainPageBase&amp;lt;TApp&gt;

       where TApp : AppLauncherBase, new()

    {



        public static AutomationElement Window

        {

            get { return PageBase&amp;lt;TApp&gt;.Window; }

            set { PageBase&amp;lt;TApp&gt;.Window = value; }

        }



        public static AutomationElement TextBoxSource

        {

            get { return PageBase&amp;lt;TApp&gt;.FindControlByAutomationId("txtSource"); }

        }



        public static AutomationElement TextBoxTarget

        {

            get { return PageBase&amp;lt;TApp&gt;.FindControlByAutomationId("txtTarget"); }

        }



        public static AutomationElement Button

        {

            get { return PageBase&amp;lt;TApp&gt;.FindControlByAutomationId("btnSubmit"); }

        }

    }

}

&lt;/pre&gt;

&lt;p&gt;Notice we are using some helper classes to find the control. However, what happens is that the context for this application is recognized as Silverlight, so the label we pass (for example, &lt;code&gt;txtTarget&lt;/code&gt;) is appended with the Silverlight designation. Ultimately, our control dictionary is accessed with the key &lt;code&gt;txtTarget_Silverlight&lt;/code&gt;, which then maps to our automation id of "TargetText" and this is how the automation peer is found. If we had a WPF application that was sharing code, we could simply add a WPF-specific entry and name the automation peer something completely different.

&lt;p&gt;&lt;b&gt;Add the Test Class&lt;/b&gt;

&lt;p&gt;OK, now that all of the infrastructure is in place, we can add our test! Go into the automatically generated &lt;code&gt;UnitTest1.cs&lt;/code&gt; class. Remember how I told you there were two steps we needed to take in order for the control resource file to be available for testing? This is where we'll make the second step. We're going to add deployment items for the test project as well as the web project. This ensures that both the resources and the test web page are copied to the test sandbox so they are available. Add this code to the top of the class:
&lt;pre class="brush: csharp;"&gt;
namespace UIAutomation.Test

{    

#if DEBUG

    [DeploymentItem(@".\UIAutomation.Test\bin\Debug")]

    [DeploymentItem(@".\UIAutomation.Web", "SL")]

#else

    [DeploymentItem(@".\UIAutomation.Test\bin\Release")]    

    [DeploymentItem(@".\UIAutomation.Web\","SL")]    

#endif

    [TestClass]

    public class UnitTest1

&lt;/pre&gt;

&lt;p&gt;We're instructing the test engine to copy the contents of the test output to the test directory. We also want to create a subdirectory called "SL" and put the output of the web project there. This gives us a path to our test page so we can run the unit tests. We also need to configure the test to use the deployment hints.

&lt;p&gt;Under the main solution, there should be a folder called &lt;code&gt;Solution Items&lt;/code&gt;. Double-click on the file &lt;code&gt;Local.testsettings&lt;/code&gt;.

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=314&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;Click on the deployment setting, and make sure that &lt;code&gt;Enable Deployment&lt;/code&gt; is checked. Once checked, click the Apply button in the lower right corner of the dialog.

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=316&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;Change the class to inherit from the &lt;code&gt;FixtureBase&lt;/code&gt; provided by Prism:
&lt;pre class="brush: csharp;"&gt;
[TestClass]    

public class UnitTest1 : FixtureBase&amp;lt;SilverlightAppLauncher&gt;

&lt;/pre&gt;

&lt;p&gt;Set up the using statements to include the namespaces we'll need:
&lt;pre class="brush: csharp;"&gt;
using System.Reflection;

using System.Threading;

using AcceptanceTestLibrary.Common;

using AcceptanceTestLibrary.Common.Silverlight;

using AcceptanceTestLibrary.TestEntityBase;

using AcceptanceTestLibrary.UIAWrapper;

using Microsoft.VisualStudio.TestTools.UnitTesting;

&lt;/pre&gt;

&lt;p&gt;Now, let's add some code to launch the browser and load the Silverlight test page, as well as tear it down when the test is finished. You'll want to tweak the delays to a value that works well for you. Put this at the top of the class:
&lt;pre class="brush: csharp;"&gt;
        private const string APP_PATH = @"\SL\UIAutomationTestPage.html";

        private const string APP_TITLE = "UIAutomation";



        #region Additional test attributes

        // Use TestInitialize to run code before running each test 

        [TestInitialize]

        public void MyTestInitialize()

        {

            var currentOutputPath = (new System.IO.DirectoryInfo(Assembly.GetExecutingAssembly().Location)).Parent.FullName;



            MainPageBase&amp;lt;SilverlightAppLauncher&gt;.Window = LaunchApplication(currentOutputPath + APP_PATH, APP_TITLE)[0];

            Thread.Sleep(5000);

        }



        // Use TestCleanup to run code after each test has run

        [TestCleanup]

        public void MyTestCleanup()

        {

            PageBase&amp;lt;SilverlightAppLauncher&gt;.DisposeWindow();

            SilverlightAppLauncher.UnloadBrowser(APP_TITLE);

        }



        #endregion

&lt;/pre&gt;

&lt;p&gt;We are using the Silverlight application launcher, a helper provided with the Prism project, to launch our test page. Notice that we get the output directory for the test that is running, then append the path to the test page. The test page is underneath the &lt;code&gt;SL&lt;/code&gt; subdirectory because that's how we defined it with the deployment item.

&lt;p&gt;Now that we have it launched and ready to tear down, we can write the actual automation test. Here's what we'll do:

&lt;ol&gt;
&lt;li&gt;Simulate typing text into the source text box 
&lt;li&gt;Confirm that the target text box is blank 
&lt;li&gt;Simulate clicking the button 
&lt;li&gt;Confirm that the target text box now has the text we entered into the source text box&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;Here's how we do it:
&lt;pre class="brush: csharp;"&gt;
[TestMethod]

public void TextBoxSubmission()

{

    const string TESTVALUE = "TestValue";



    // set up the value

    var txtBox = MainPageBase&amp;lt;SilverlightAppLauncher&gt;.TextBoxSource;

    Assert.IsNotNull(txtBox, "Text box is not loaded");

    txtBox.SetValue(TESTVALUE);

    Thread.Sleep(1000);

    Assert.AreEqual(txtBox.GetValue(), TESTVALUE);



    // ensure the text block is empty to start with

    var txtBox2 = MainPageBase&amp;lt;SilverlightAppLauncher&gt;.TextBoxTarget;

    Assert.IsNotNull(txtBox2, "Target text box is not loaded.");

    Assert.IsTrue(string.IsNullOrEmpty(txtBox2.GetValue()), "Target text box is not empty.");



    var btnSubmit = MainPageBase&amp;lt;SilverlightAppLauncher&gt;.Button;

    Assert.IsTrue(btnSubmit.Current.IsEnabled, "Submit Button is not enabled");

    btnSubmit.Click();



    Thread.Sleep(1000);



    var actual = txtBox2.GetValue();



    Assert.AreEqual(TESTVALUE, actual, "Text block was not updated.");



    Thread.Sleep(1000);

}

&lt;/pre&gt;

&lt;p&gt;As you can see, writing the automation tests is relatively straightforward. We don't have "record and playback" but it's easy to grab a control, tell it to do something, and then query the result. Build the project and make sure there are no errors.

&lt;p&gt;&lt;b&gt;Run the Test&lt;/b&gt;

&lt;p&gt;Remember what I mentioned earlier about lots of steps? We're there. We've set it up, and should be good to go. If you have issues, go back and check the steps to make sure you didn't miss anything. Again, once you get the hang of it, you'll find it's not that difficult to get up and running and to write some great automation tests. There are good examples in the Prism samples, specifically in the MVVM quick start.

&lt;p&gt;Let's open the test view:

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=318&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;Select the test and click "Debug Selection":

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=320&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;You should eventually see a browser window pop up. The browser may complain about security. If this happens, simply click on the yellow bar and allow the blocked content. Be sure to do this before the launch times out:

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=325&amp;amp;g2_serialNumber=2" /&gt;

&lt;p&gt;You can literally watch the Silverlight application appear in the browser, then see the text entered into the source box, and eventually the button will click and the text should post to the target box. If all goes well, you'll get the familiar green check box:

&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;amp;g2_itemId=322&amp;amp;g2_serialNumber=1" /&gt;

&lt;p&gt;There you go ... Silverlight UI automation! If you've made it this far, then you have what you need to set this up for your own projects. I've heard of some companies who don't use Silverlight because they are under the impression it doesn't support automated testing. If you're at one of those companies, be sure to go grab your manager, drag them to your cube and show them that it should now be an approved platform for you and your fellow developers!

&lt;p&gt;&lt;a title="Jeremy Likness" href="http://jeremylikness.com/"&gt;&lt;img title="Jeremy Likness" border="0" alt="Jeremy Likness" src="http://jeremylikness.com/signature.gif" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-8849764732324090917?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/8849764732324090917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/silverlight-ui-automation-testing-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/8849764732324090917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/8849764732324090917'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/silverlight-ui-automation-testing-using.html' title='Silverlight UI Automation Testing using Prism 4.0'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-5430711359725226104</id><published>2010-07-25T13:11:00.004-04:00</published><updated>2010-07-25T13:36:27.866-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Managed Extensibility Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='locator'/><title type='text'>Using Hints for Generic MEF Exports</title><content type='html'>&lt;p&gt;It is very common to have base classes and interfaces that use generic types to define standard behaviors across business applications. One challenge with the Managed Extensibility Framework is that it doesn't directly support generic exports and imports: in other words, there is no way to effectively do the following: 
&lt;pre class="brush: csharp;"&gt;
...
[ImportMany(AllowRecomposition=true)]
public IService&amp;lt;,&gt;[] GenericService { get; set; }
...
&lt;/pre&gt;
&lt;p&gt;While there is a &lt;a href="http://mefcontrib.codeplex.com/wikipage?title=Generic%20Catalog&amp;referringTitle=Documentation%20%26%20Features" target="_blank"&gt;GenericCatalog&lt;/a&gt; you can use, I wanted something a little more flexible and specific to the application. 
&lt;p&gt;&lt;b&gt;The Example Service&lt;/b&gt;
&lt;p&gt;Let's assume we have an example "service" interface that does something to an instance of a type. We define the interface like this: 
&lt;pre class="brush: csharp;"&gt;
public interface IService&amp;lt;T&gt; 
{
   void DoSomething(T instance); 
}
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;The Locator&lt;/b&gt;
&lt;p&gt;The goal is to have a composite application that automatically picks up services that support different types of &lt;code&gt;T&lt;/code&gt; and a locator that easily gives us the instance we are looking for. The locator looks like this: 
&lt;pre class="brush: csharp;"&gt;
public interface IServiceLocator
{
    IService&amp;lt;T&gt; GetServiceFor&amp;lt;T&gt;();
}
&lt;/pre&gt;
&lt;p&gt;This allows us to easily ask for the service, and do something with it: 
&lt;pre class="brush: csharp;"&gt;
var service = serviceLocator.GetServiceFor&amp;lt;MyClass&gt;();
service.DoSomething(myInstance);
&lt;/pre&gt;
&lt;p&gt;The problem with the locator is that we don't have a basic "generic" import for the various services, and we'd have to do a lot of dancing with reflection to parse out types as they became available in order to wire them in. In this case, I felt it was easier to come up with an intermediary class to facilitate finding the service. 
&lt;p&gt;&lt;b&gt;Hinting Around&lt;/b&gt;
&lt;p&gt;I call it a &lt;i&gt;hint&lt;/i&gt; because it hints to the locator where to find the right service. The interface for a service hint looks like this: 
&lt;pre class="brush: csharp;"&gt;
public interface IServiceLocatorHint
{
    bool ServicesType&amp;lt;T&gt;();
    IServiceInterface&amp;lt;T&gt; GetServiceFor&amp;lt;T&gt;();
}
&lt;/pre&gt;
&lt;p&gt;As you can see, the hint has two methods. One determines whether or not the hint is capable of producing the service for a given type, and the other returns that service. Now, let's assume in a dynamically loaded module we implement the service contract for &lt;code&gt;MyClass&lt;/code&gt; using a class called &lt;code&gt;MyService&lt;/code&gt;. It looks like this:
&lt;pre class="brush: csharp;"&gt;
[Export]
public class MyService : IService&amp;lt;MyClass&gt; 
{
   void DoSomething(MyClass instance) 
   {
      Debug.WriteLine(instance.ToString());
   }
}
&lt;/pre&gt;
&lt;p&gt;Notice I am exporting the service as the concrete type. Next, I build a simple hint: 
&lt;pre class="brush: csharp;"&gt;
[Export(typeof(IServiceLocatorHint))]
public class MyModuleHints : IServiceLocatorHint
{
    [Import]
    public MyService MyServiceInstance { get; set; }
 
    public bool ServicesType&amp;lt;T&gt;()
    {
        return typeof(T).Equals(typeof(MyClass));
    }

    public IServiceInterface&amp;lt;T&gt; GetServiceFor&amp;lt;T&gt;()
    {
        if (ServicesType&amp;lt;T&gt;())
        {
            return (IServiceInterface&amp;lt;T&gt;) MyServiceInstance;
        }

        throw new NotSupportedException();
    }

}
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Putting it all Together&lt;/b&gt;
&lt;p&gt;Now that we have the service wired by MEF with all dependencies, and the hint wired as well, we can implement the locator class. 
&lt;pre class="brush: csharp;"&gt;
[Export(typeof(IServiceLocator))]
public class ServiceLocator : IServiceLocator
{
    [ImportMany(AllowRecomposition = true)]
    public IServiceLocatorHint[] Hints { get; set; }

    public IServiceInterface&amp;lt;T&gt; GetServiceFor&amp;lt;T&gt;()
    {
        var serviceHint = (from hint in Hints 
                        where hint.ServicesType&amp;lt;T&gt;() 
                        select hint).FirstOrDefault();

        if (serviceHint == null)
        {
            throw new NotSupportedException();
        }

        return serviceHint.GetServiceFor&amp;lt;T&gt;();
    }
}
&lt;/pre&gt;
&lt;p&gt;The class is simple. As modules are loaded, the main list is recomposed to include any new hints that were found. When the user requests a service, it simply finds the hint that satisfies the type, then returns the corresponding service.
&lt;p&gt;Using this flexible locator class is as simple as importing it, then asking for the service: 
&lt;pre class="brush: csharp;"&gt;
[Import]
public IServiceLocator Locator { get; set; }

public void ProcessClass(MyClass item)
{
   var service = Locator.GetServiceFor&amp;lt;MyClass&gt;();
   service.DoSomething(item); 
}
&lt;/pre&gt;
&lt;p&gt;If you have multiple services in a module, you can easily build a base class that uses a dictionary to register the instances and streamline the methods that check for support and return the instances. The power of MEF is that new services are easily discovered as plugins and extensions are loaded into the main application, and you can basically build an application around what you &lt;i&gt;don't&lt;/i&gt; know yet, rather than having to constrain it based upon what you do know. 
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-5430711359725226104?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/5430711359725226104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/using-hints-for-generic-mef-exports.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/5430711359725226104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/5430711359725226104'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/using-hints-for-generic-mef-exports.html' title='Using Hints for Generic MEF Exports'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-2111050955201534446</id><published>2010-07-17T13:22:00.005-04:00</published><updated>2010-07-17T14:11:00.411-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows phone 7'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight 4'/><category scheme='http://www.blogger.com/atom/ns#' term='windows phone 7 series'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='sterling'/><category scheme='http://www.blogger.com/atom/ns#' term='OODB'/><title type='text'>Sterling OODB v0.1 Alpha Released!</title><content type='html'>&lt;p&gt;I'm please to share that I released the alpha version of the Sterling Object-Oriented Database for Silverlight 4.0 and Windows Phone 7.0 applications today.
&lt;p&gt;I dug into more details about the project in &lt;a href="http://csharperimage.jeremylikness.com/2010/07/introducing-sterling-object-oriented.html" target="_blank"&gt;this introductory post&lt;/a&gt;. There have not been many significant changes to the source code since then, but I did create a set up project that installs the DLLs and configures the registry keys so they appear in the "add reference" dialog on the .NET tab for both Silverlight and Windows Phone 7 applications.
&lt;p&gt;Please take a moment to read and participate in the release discussion that you can find &lt;a href="http://sterling.codeplex.com/Thread/View.aspx?ThreadId=219781" target="_blank"&gt;by clicking here&lt;/a&gt;. You can grab the installer and the source code &lt;a href="http://sterling.codeplex.com/releases/view/48124" target="_blank"&gt;at this link&lt;/a&gt;.
&lt;p&gt;Our team is really some part time help and me and we all have full time careers so it's tough to give the project the attention and detail it deserves. I learned in the past that sometimes it's more important to "get it going" than to "get it perfect." Instead of holding back months before formalizing the release, I wanted to get it out there so people can use it, comment on it, and provide feedback.
&lt;p&gt;You can help our team in two very important ways. First, if you use the tool, please provide feedback, both positive and constructive, so we know where/when/how the project is being used and how to prioritize future improvements.
&lt;p&gt;Second, if you are a developer and feel you can contribute your skills, please contact me and we can discuss you joining the team. Probably the two biggest needs on the team right now are someone who has the time to build out a more thorough reference application for the Windows Phone 7 version, and someone who is an installation wizard to help improve the install process. The documentation is also rudimentary so technical writers are welcome as well. 
&lt;p&gt;Thanks, and I look forward to your feedback!
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-2111050955201534446?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://sterling.codeplex.com/releases/view/48124' title='Sterling OODB v0.1 Alpha Released!'/><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/2111050955201534446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/sterling-oodb-v01-alpha-released.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/2111050955201534446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/2111050955201534446'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/sterling-oodb-v01-alpha-released.html' title='Sterling OODB v0.1 Alpha Released!'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-7081171856441866798</id><published>2010-07-15T13:07:00.004-04:00</published><updated>2010-07-15T13:13:21.995-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='silverlight 4'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='profiling'/><title type='text'>Silverlight Profiling Part 2: The Easy Way</title><content type='html'>&lt;p&gt;After posting about profiling Silverlight 4 out of the box, the author of a tool was kind enough to share with me his &lt;a href="http://xteprofiler.net/" target="_blank"&gt;free .NET profiling tool&lt;/a&gt;. It's free, and it does a lot more than Silverlight. The manual is very straightforward but I wanted to make a quick an easy "light tour" to show you how I profiled the X-Fit app using the tool. In less than 4 minutes I'll run two different profiles, a trace and a memory scan. The memory scan lets you see individual classes, number of objects, size, etc, so the video doesn't tap into the full features, but should show how fast and easy it makes profiling.
&lt;p&gt;Sorry, this was quick and dirty over lunch so I didn't encode it to Silverlight - Jing and ScreenToaster came through (&lt;a href="http://www.screencast.com/t/MzA4NDhkZTEt" target="_blank"&gt;link to new window&lt;/a&gt;): 
&lt;p&gt;&lt;object id="scPlayer" class="embeddedObject" width="640" height="500" type="application/x-shockwave-flash" data="http://content.screencast.com/users/JeremyLikness/folders/Jing/media/e85c83af-67b3-4722-a0d8-c237f6bb710d/jingswfplayer.swf" &gt; &lt;param name="movie" value="http://content.screencast.com/users/JeremyLikness/folders/Jing/media/e85c83af-67b3-4722-a0d8-c237f6bb710d/jingswfplayer.swf" /&gt; &lt;param name="quality" value="high" /&gt; &lt;param name="bgcolor" value="#FFFFFF" /&gt; &lt;param name="flashVars" value="thumb=http://content.screencast.com/users/JeremyLikness/folders/Jing/media/e85c83af-67b3-4722-a0d8-c237f6bb710d/FirstFrame.jpg&amp;containerwidth=908&amp;containerheight=723&amp;content=http://content.screencast.com/users/JeremyLikness/folders/Jing/media/e85c83af-67b3-4722-a0d8-c237f6bb710d/xfitprofile.swf&amp;blurover=false" /&gt; &lt;param name="allowFullScreen" value="true" /&gt; &lt;param name="scale" value="showall" /&gt; &lt;param name="allowScriptAccess" value="always" /&gt; &lt;param name="base" value="http://content.screencast.com/users/JeremyLikness/folders/Jing/media/e85c83af-67b3-4722-a0d8-c237f6bb710d/" /&gt;&lt;/object&gt;
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-7081171856441866798?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.screencast.com/t/MzA4NDhkZTEt' title='Silverlight Profiling Part 2: The Easy Way'/><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/7081171856441866798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/silverlight-profiling-part-2-easy-way.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/7081171856441866798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/7081171856441866798'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/silverlight-profiling-part-2-easy-way.html' title='Silverlight Profiling Part 2: The Easy Way'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-5999155412017381492</id><published>2010-07-14T17:50:00.001-04:00</published><updated>2010-07-14T17:52:53.560-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='powershell'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight 4'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='profiling'/><title type='text'>Performance Profiling Silverlight 4 Step-by-Step</title><content type='html'>&lt;p&gt;It turns out you &lt;i&gt;can&lt;/i&gt; profile Silverlight 4 applications. Really! But the steps are scattered about the web in bits and pieces, so I wrote this to pull them all together. I'm going to use my reference X-Fit application for this, but you can obviously insert your own. Here we go!
&lt;p&gt;&lt;b&gt;Set up PowerShell&lt;/b&gt;
&lt;p&gt;Yeah, we're going to make things a little easier and set up PowerShell. If you're not familiar with PowerShell, don't worry. Here is a decent &lt;a href="http://en.wikipedia.org/wiki/Windows_PowerShell" target="_blank"&gt;description of PowerShell&lt;/a&gt;, but if you really want to get deep into it, read Wintellectual &lt;a href="http://www.wintellect.com/CS/blogs/jrobbins/default.aspx" target="_blank"&gt;John Robbin's blog&lt;/a&gt; which is full of goodness. Really the main thing you want to do is to &lt;a href="http://www.tech-recipes.com/rx/2513/powershell_enable_script_support/" target="_blank"&gt;enable script support&lt;/a&gt; in PowerShell, and get familiar with &lt;a href="http://technet.microsoft.com/en-us/library/ee176949.aspx" target="_blank"&gt;running scripts&lt;/a&gt;.
&lt;p&gt;&lt;b&gt;Set up your Symbol Server&lt;/b&gt;
&lt;p&gt;We're going to need a valid symbol server to make things work. If you're not familiar with this, it's basically a place that Windows debug can go to figure out symbols (labels, names, etc) for code as you are debugging, profiling, etc. John Robbins has a fantastic script that you can use to set this up. 
&lt;ol&gt;&lt;li&gt;Get John Robbins' script &lt;a href="http://www.wintellect.com/CS/blogs/jrobbins/archive/2010/07/06/updated-powershell-script-for-setting-your-symbol-paths.aspx" target="_blank"&gt;here&lt;/a&gt; (just copy it and save it to a file called "symbolsetup.ps1" and if I have to tell you without the quotes, you're not ready to profile)&lt;li&gt;Execute the script in PowerShell. You must specify the full path and add a flag. I do it like this: &lt;code&gt;&amp; "c:\users\jeremylikness\my documents\powershell\symbolsetup.ps1" -public&lt;/code&gt;&lt;li&gt;This should set it all up for you. &lt;i&gt;Beware! The first time you debug, you will have quite a delay as all of the symbols are downloaded - this only happens once.&lt;/i&gt;&lt;/ol&gt;
&lt;p&gt;&lt;b&gt;Prepare your Application&lt;/b&gt;
&lt;p&gt;To profile, you must compile the application in &lt;i&gt;release&lt;/i&gt; mode. Yes, you read that correctly. The symbol server will provide all of the symbols and details necessary, but you must compile in release mode for this to work. 
&lt;p&gt;In our example, we'll pull down the &lt;a href="http://csharperimage.jeremylikness.com/2010/06/advanced-silverlight-applications-using.html" target="_blank"&gt;Reference X-Fit Application&lt;/a&gt;. Download it, unzip it, and build it in release mode.
&lt;p&gt;While you can debug most applications from a test page, this application uses dynamic modules so it is best to publish it to a site. You can use your local development environment, but it's easier if you just make an application in IIS. I'll leave that to you, but when we profile, the parameter we'll pass to launch it will be some type of URL. 
&lt;p&gt;&lt;b&gt;Let's Profile!&lt;/b&gt;
&lt;p&gt;First, credits go to the &lt;a href="http://blogs.msdn.com/b/profiler/archive/2010/04/26/vs2010-silverlight-4-profiling.aspx" target="_blank"&gt;Windows Profiler Team&lt;/a&gt; for their detailed post for this. It contains what I'm going to share here, but I was missing some of the setup. 
&lt;p&gt;Go to your start menu, navigate to Visual Studio 2010, Tools, and select the command prompt &lt;i&gt;as an Administrator&lt;/i&gt;.
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=275&amp;g2_serialNumber=1" title="Launch the Visual Studio 2010 Command Prompt" alt="Launch the Visual Studio 2010 Command Prompt"/&gt;
&lt;ol&gt;&lt;li&gt;Navigate to the release directory for the main XAP file. In this case, it is under &lt;code&gt;XFit/Bin/Release&lt;/code&gt; for the main XAP in X-Fit. If you have dynamic modules, you can copy the DLL and PDB files to this directory.&lt;li&gt;Open Task Manager and sort by image name. Note the PIDs of the existing iexplore.exe processes.&lt;li&gt;Set up the profiling environment:&lt;br/&gt;&lt;code&gt;vsperfclrenv /sampleon&lt;/code&gt;&lt;li&gt;Launch a new process, passing the page you want to debug:&lt;br/&gt;&lt;code&gt;"c:\program files (x86)\internet explorer\iexplore.exe" http://localhost/xfit/&lt;/code&gt;&lt;li&gt;Note the new IE process (Hint: you can also go into Visual Studio and choose "attach to process" to see the title/type of process to narrow down the correct one that is hosting the Silverlight application &amp;mdash; don't actually attach, just use this to get the process identifier)&lt;li&gt;Start profiling the process (in this case, my PID was 4436):&lt;br/&gt;&lt;code&gt;VSPerfCmd /start:sample /output:xfitdata /attach:4436&lt;/code&gt;&lt;li&gt;Now go into the application and perform some actions. I created an account, then looked at my BMI, then updated my account and put in some errors and hovered over some information icons just to get a good sample&lt;li&gt;End the session:&lt;br/&gt;&lt;code&gt;VSPerfCmd /detach&lt;/code&gt;&lt;br/&gt;&lt;code&gt;VSPerfCmd /shutdown&lt;/code&gt;&lt;br/&gt;&lt;code&gt;VSPerfClrEnv /off&lt;/code&gt;&lt;/ol&gt;
&lt;p&gt;&lt;b&gt;Examine the Data&lt;/b&gt;
&lt;p&gt;Once I shut everything down, a new file was created called &lt;code&gt;xfitdata.vsp&lt;/code&gt;. Now the fun part: analyzing the data. In Visual Studio 2010, you can go to File -&gt; Open File and navigate to the VSP file to open it. You'll see a message that it is analyzing the file. This may take several minutes, so be patient. If you have your output window open, you should see messages as the symbols are analyzed:
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=278&amp;g2_serialNumber=2" title="Loading Symbols" alt="Loading Symbols"/&gt;
&lt;p&gt;Probably the easiest way to filter the data is to go to the module view:
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=280&amp;g2_serialNumber=1" alt="Module View" title="Module View"/&gt;
&lt;p&gt;Then you can expand and see where the application is spending it's time:
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=283&amp;g2_serialNumber=2" alt="Expanding Profiler Info" title="Expanding Profiler Info"/&gt;
&lt;p&gt;If you double-click on the higher level item, a window will open with the details including (if available) the source code.
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=286&amp;g2_serialNumber=2" title="Sample Profiler Data" alt="Sample Profiler Data"/&gt;
&lt;p&gt;There you have it ... step-by-step profiling Silverlight 4.
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-5999155412017381492?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/5999155412017381492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/performance-profiling-silverlight-4.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/5999155412017381492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/5999155412017381492'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/performance-profiling-silverlight-4.html' title='Performance Profiling Silverlight 4 Step-by-Step'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-5250469008926080998</id><published>2010-07-13T11:32:00.003-04:00</published><updated>2010-07-13T11:49:35.599-04:00</updated><title type='text'>What YOU Are Interested In</title><content type='html'>&lt;p&gt;I was very excited to see two of my blog posts featured in the 900th issue of &lt;a href="http://geekswithblogs.net/WynApseTechnicalMusings/archive/2010/07/10/140867.aspx" target="_blank"&gt;Silverlight Cream&lt;/a&gt; which ranked the top articles of 2010 thus far. These were &lt;a href="http://www.silverlightcream.com/SilverlightCreamRedirect.aspx?LinkID=5179" target="_blank"&gt;Top 10 Silverlight Myths and Facts to Bust Them&lt;/a&gt; (#4) and &lt;a href="http://www.silverlightcream.com/SilverlightCreamRedirect.aspx?LinkID=5021" target="_blank"&gt;Simple Dialog Service in Silverlight&lt;/a&gt; (#17).
&lt;p&gt;I appreciate your interest and out of curiosity decided to examine my own blog to see what trends look like for the past year. What posts are you looking at the most? And where do you spend most of your time? Here's what I found: 
&lt;p&gt;&lt;b&gt;Last 6 Months&lt;/b&gt;
&lt;ol&gt;&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html" target="_blank"&gt;Model-View-ViewModel (MVVM) Explained&lt;/a&gt;&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2010/03/mvvm-with-mef-in-silverlight-video.html" target="_blank"&gt;MVVM with MEF in Silverlight Video Tutorial&lt;/a&gt;&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2009/11/dynamic-module-loading-with-silverlight.html" target="_blank"&gt;Dynamic Module Loading with Silverlight Navigation using PRISM&lt;/a&gt;&lt;/ol&gt;
&lt;p&gt;&lt;b&gt;Last 3 Months&lt;/b&gt;
&lt;ol&gt;&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html" target="_blank"&gt;Model-View-ViewModel (MVVM) Explained&lt;/a&gt;&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2010/03/mvvm-with-mef-in-silverlight-video.html" target="_blank"&gt;MVVM with MEF in Silverlight Video Tutorial&lt;/a&gt;&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2009/12/prism-mef-and-mvvm-part-1-of-3-unity.html" target="_blank"&gt;PRISM, MEF, and MVVM Part 1 of 3: Unity Glue&lt;/a&gt;&lt;/ol&gt;
&lt;p&gt;&lt;b&gt;Last Month&lt;/b&gt; 
&lt;ol&gt;&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html" target="_blank"&gt;Model-View-ViewModel (MVVM) Explained&lt;/a&gt;&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2010/07/introducing-sterling-object-oriented.html" target="_blank"&gt;Introducing Sterling, the OODB for Silverlight and Windows Phone 7&lt;/a&gt;&lt;li&gt;&lt;a href="http://csharperimage.jeremylikness.com/2010/06/tips-and-tricks-for-inotifypropertychan.html" target="_blank"&gt;Tips and Tricks for INotifyPropertyChanged&lt;/a&gt;&lt;/ol&gt;
&lt;p&gt;I'm assuming you actually &lt;i&gt;read&lt;/i&gt; the posts because you spent an average of 4 - 5 minutes on each of the top ones.
&lt;p&gt;What does this tell me? It shows there is a major interest in dynamic modules, in MEF, in local storage for Silverlight, and of course the Model-View-ViewModel pattern. This is good, because these are topics I consistently write about and speak about at public events. However, one other thing I've found is just as important.
&lt;p&gt;&lt;i&gt;We need more quick starts, easy step-by-step tutorials, and guidance for these patterns!&lt;/i&gt;
&lt;p&gt;With the few talks I've done that provided feedback from the audience, the lower ratings are always tied to either "too much content" or "too advanced." I appreciate that feedback and it tells me you want more simple, 1-2-3 style posts and snippets of information. I also know my future talks should focus on the fundamentals and not dive into advanced topics unless I know for a fact the audience is going to have experience coming into it.
&lt;p&gt;I appreciate all of your feedback, both direct and indirect. Can you help out even more with this post? I'd love to hear what blog posts, articles, video tutorials, and talks you would like to see but feel haven't been addressed. Use the comments below to share with me what you'd like to see more of, and how you'd like to see it. It will only help me improve the content that I share here and at users groups.
&lt;p&gt;Thanks!
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-5250469008926080998?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/5250469008926080998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/what-you-are-interested-in.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/5250469008926080998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/5250469008926080998'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/what-you-are-interested-in.html' title='What YOU Are Interested In'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-6309667385178641205</id><published>2010-07-02T16:01:00.007-04:00</published><updated>2010-07-02T17:08:16.873-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='OODB'/><category scheme='http://www.blogger.com/atom/ns#' term='isolated storage'/><title type='text'>Introducing Sterling, the Object-Oriented Database for Silverlight and Windows Phone 7</title><content type='html'>&lt;p&gt;Today, I'm excited to share a project that I've been working on for some time now. The project, called Sterling (for Sterling Silverlight, of course!) is a very light weight approach to handling serialization and deserialization to and from isolated storage. I call it an object-oriented database because it provides LINQ to Object queries over keys and indexes. 
&lt;p&gt;I guess the timing works well ... I was recently honored with the 2010 Microsoft Most Valuable Professional (MVP) award for my work with Silverlight. Much of this award is about what we do for the community, and this is one of my first major efforts to put a utility and open source project out there. Lots of hours went into this but I hope there will be great benefits for those of you who find value in using it.
&lt;p&gt;Sterling is not yet released and I don't anticipate we'll have an alpha ready until late July. I work on many projects for my company, so this effort has been primarily late nights or snatches during lunch and breaks and will probably continue to be so. I'm excited that some members of the community have offered to reach out and help push development forward. 
&lt;p&gt;First, let me emphasize that Sterling is not intended as a replacement for a robust, transactional database system. There are some commercial and non-commercial solutions that are optimized for performance and massive scale. I wrote Sterling to be a simple serialization engine to avoid having to deal with the goop of writing my own serializers all of the time. I also know that even if you have a simple list of contacts, querying the contact names is going to be a priority over deserializing all of them, so I built a key and index infrastructure to facilitate storing key items in memory so you can bind to lists and combo-boxes without de-serializing the entire object.
&lt;p&gt;Having said all of this, while a lot of more powerful features may not exist, my goal was to hit 80% of the needs with 20% of the footprint. Not only is Sterling incredibly lightweight, but extensible and available on Windows Phone 7.
&lt;p&gt;Here are the key goals I had in mind: 
&lt;p&gt;&lt;b&gt;Non-intrusive&lt;/b&gt;
&lt;p&gt;I don't like mangling my classes to persist them. I didn't want to force anyone to inherit from a base class or decorate the class with attributes to make it work. I believe I've achieved this goal. Defining a "table" to sterling is as simple as passing a type and a lambda expression that returns the key: 
&lt;pre class="brush: csharp;"&gt;
public override List&amp;lt;ITableDefinition&gt; _RegisterTables()
{
 return new List&amp;lt;ITableDefinition&gt;
                       {
                           CreateTableDefinition&amp;lt;Contact,string&gt;(c =&gt; c.Email)
                       }
}
&lt;/pre&gt;
&lt;p&gt;I can even do this for sealed classes or third-party classes - whatever your code can see, Sterling can, too. Sterling automatically serializes the same values that the &lt;code&gt;BinaryWriter&lt;/code&gt; class supports. If you need something custom, no problem - just define a serializer of your own and register it with Sterling.
&lt;p&gt;&lt;b&gt;Lightweight&lt;/b&gt;
&lt;p&gt;I wanted Sterling to fit on the Windows Phone 7 and also to facilitate building projects without bloating them. I purposefully kept it lightweight. Currently the DLL weighs in at only 70 kilobytes, which I believe is very trivial compared to some solutions I've seen.
&lt;p&gt;&lt;b&gt;Flexible and Portable&lt;/b&gt;
&lt;p&gt;Again, these are both features that collapse into the previous items. By keeping it flexible, I can accommodate needs I didn't know at design time. There is a very loose interface for logging and for extending serialization. This allows you to do pretty much whatever you like, without having to think about the underpinnings of setting up tables and folders and checking if they exist, etc. Portability means it was easy to build on Windows Phone 7 and should be very easy to bring forward into future versions of Silverlight.
&lt;h1&gt;The Reference Application&lt;/h1&gt;
&lt;p&gt;The easiest way to get to know Sterling is by the reference application. I will warn you that it takes a long time to build because of the time it takes to initially serialize. I decided a good test case would be the USRDA nutrient database. It contains over 500,000 data elements. I had to write some parsers to take the source text-based database files and turn them into data objects that Sterling could deal with, but once the conversion is done, you can see the power of how Sterling operates.
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=267&amp;g2_serialNumber=2" title="Sterling building the local database"/&gt;
&lt;p&gt;The left column shows a custom logger I made that is spitting out Sterling log information. The data models were straightforward. A food group is a general "category" for foods to fall under. The food description is an actual food item, and contains a list of nutrient data elements (things like calories, protein, vitamin A, etc). These point to a nutrient definition.
&lt;pre class="brush: csharp;"&gt;
public class FoodGroup
{
    public int Id { get; set; }
    public string GroupName { get; set; }
}

public class NutrientDefinition
{
    public int Id { get; set; }

    public string UnitOfMeasure { get; set; }

    public string Tag { get; set; }

    public string Description { get; set; }

    public int SortOrder { get; set; }
}

public struct NutrientDataElement
{
    public int NutrientDefinitionId { get; set; }
    public double AmountPerHundredGrams { get; set; }
}

public class FoodDescription
{
    public FoodDescription()
    {
        Nutrients = new List&lt;NutrientDataElement&gt;();
    }

    public int Id { get; set; }

    public int FoodGroupId { get; set; }

    public string Description { get; set; }

    public string Abbreviated { get; set; }

    public string CommonName { get; set; }

    public string Manufacturer { get; set; }

    public string InedibleParts { get; set; }

    public double PctRefuse { get; set; }

    public string ScientificName { get; set; }

    public double NitrogenFactor { get; set; }

    public double ProteinCalories { get; set; }

    public double FatCalories { get; set; }

    public double CarbohydrateCalories { get; set; }

    public List&amp;t;NutrientDataElement&gt; Nutrients { get; set; }
}
&lt;/pre&gt;
&lt;p&gt;Because I have a struct for the nutrient information, I had to provide a custom serializer: 
&lt;pre class="brush: csharp;"&gt;
public class FoodSerializer : BaseSerializer  
{
    public override bool CanSerialize(Type targetType)
    {
        return targetType.Equals(typeof (NutrientDataElement));                
    }

    public override void Serialize(object target, BinaryWriter writer)
    {
        var data = (NutrientDataElement)target;
        writer.Write(data.NutrientDefinitionId);
        writer.Write(data.AmountPerHundredGrams);
    }

    public override object Deserialize(Type type, BinaryReader reader)
    {
        return new NutrientDataElement
                    {
                        NutrientDefinitionId = reader.ReadInt32(),
                        AmountPerHundredGrams = reader.ReadDouble()
                    };
    }
}
&lt;/pre&gt;
&lt;p&gt;As you can see, fast and easy to do. Defining the tables took a little bit of thought. I wanted a "covered index" for food groups so I wouldn't have to de-serialize them at all. For the food descriptions, I needed an index on description and food group for fast filtering and sorting. Finally, the nutrient definitions provided an index for unit of measure and sort order (so they sort consistently in each food item).
&lt;pre class="brush: csharp;"&gt;
public class FoodDatabase : BaseDatabaseInstance
{
    public override string Name
    {
        get { return "Type Database"; }
    }

    public const string FOOD_GROUP_NAME = "FoodGroup_GroupName";
    public const string FOOD_DESCRIPTION_DESC_GROUP = "FoodDescription_Description_Group";
    public const string NUTR_DEFINITION_UNITS_DESC = "NutrientDefinition_Units_Description";
    public const string NUTR_DEFINITION_SORT = "NutrientDefinition_Sort";
        
    protected override List&amp;lt;ITableDefinition&gt; _RegisterTables()
    {
        return new List&amp;lt;ITableDefinition&gt;
                    {
                        CreateTableDefinition&amp;lt;FoodGroup, int&gt;(fg =&gt; fg.Id)
                            .WithIndex&amp;lt;FoodGroup, string, int&gt;(FOOD_GROUP_NAME, fg =&gt; fg.GroupName),
                        CreateTableDefinition&amp;lt;FoodDescription, int&gt;(fd =&gt; fd.Id)
                            .WithIndex&amp;lt;FoodDescription, string, int, int&gt;(FOOD_DESCRIPTION_DESC_GROUP,
                                                                            fd =&gt;
                                                                            Tuple.Create(fd.Description, fd.FoodGroupId)),
                        CreateTableDefinition&amp;lt;NutrientDefinition,int&gt;(nd=&gt;nd.Id)
                            .WithIndex&amp;lt;NutrientDefinition,string,string,int&gt;(NUTR_DEFINITION_UNITS_DESC,
                            nd=&gt;Tuple.Create(nd.UnitOfMeasure,nd.Description))
                            .WithIndex&amp;lt;NutrientDefinition,int,int&gt;(NUTR_DEFINITION_SORT,
                            nd=&gt;nd.SortOrder)
                    };
    }
}
&lt;/pre&gt;
&lt;p&gt;The main view model allows you to select groups and enter search terms, displays the food items, and then will show a chart breaking out nutrition information when you click on the food item. The food group list is queried using the index like this: 
&lt;pre class="brush: csharp;"&gt;
public IEnumerable&amp;lt;FoodGroup&gt; FoodGroups
{
    get
    {
        return DesignerProperties.IsInDesignTool
                    ? _samples.AsEnumerable()
                    : from fg in
                            SterlingService.Current.Database.Query&amp;lt;FoodGroup, string, int&gt;(
                                FoodDatabase.FOOD_GROUP_NAME)
                        select new FoodGroup {Id = fg.Key, GroupName = fg.Index};
    }
}
&lt;/pre&gt;
&lt;p&gt;Note that I have a default list for design-time, otherwise I run the actual query.
&lt;p&gt;When you hover over a food group, I supply a tool-tip to show the number of food items in that group. I decided to go ahead and store these in a dictionary after querying the first time, but only because I know they won't change. The converter looks like this: 
&lt;pre class="brush: csharp;"&gt;
private readonly Dictionary&amp;lt;int,int&gt; _foodCounts = new Dictionary&amp;lt;int,int&gt;();

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    var count = DesignerProperties.IsInDesignTool ? 500 : 0;
            
    var foodGroup = value as FoodGroup;
    if (foodGroup != null &amp;&amp; !DesignerProperties.IsInDesignTool)
    {
        if (_foodCounts.ContainsKey(foodGroup.Id))
        {
            count = _foodCounts[foodGroup.Id];
        }
        else
        {
            count =
                (from index in
                        SterlingService.Current.Database.Query&amp;lt;FoodDescription, string, int, int&gt;(
                            FoodDatabase.FOOD_DESCRIPTION_DESC_GROUP)
                    where index.Index.Item2.Equals(foodGroup.Id)
                    select index).Count();
            _foodCounts.Add(foodGroup.Id,count);
        }
    }

    return string.Format("There are {0} food items in this food group.", count);
}
&lt;/pre&gt;
&lt;p&gt;Here you can see I'm providing a design-time default. If I'm not in the designer, then I go ahead and calculate the amount and save it using the index I created. The index has two values (description and food group key) so I use a Tuple to access the value. None of this requires any de-serialization because I'm only touching the index.
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=269&amp;g2_serialNumber=1" title="Food group counts" alt="Food group counts"/&gt;
&lt;p&gt;The search view model uses the same index to pull food items. The query is a bit more complex. I'm not allowing you to search all 10,000 food items. You must narrow it to a category &lt;b&gt;or&lt;/b&gt; enter at least three characters of a search (the search is a containing search, not a "starts with" or "ends with"). 
&lt;pre class="brush: csharp;"&gt;
public IEnumerable&amp;lt;FoodDescriptionIndex&gt; SearchResults
{
    get
    {
        if (DesignerProperties.IsInDesignTool)
            return _sampleDescriptions.AsEnumerable();

        if (_currentGroup != null)
        {
            if (string.IsNullOrEmpty(_searchText) || _searchText.Length &lt; 3)
            {
                var query1 = from fg in
                                    SterlingService.Current.Database.Query
                                    &amp;lt;FoodDescription, string, int, int&gt;(
                                        FoodDatabase.FOOD_DESCRIPTION_DESC_GROUP)
                                where
                                    fg.Index.Item2.Equals(_currentGroup.Id)
                                select
                                    new FoodDescriptionIndex {Id = fg.Key, Description = fg.Index.Item1};

                return query1.Count() == 0 ? _noResults.AsEnumerable() : query1;
            }

            // group and search text)
            var query2 = from fg in
                        SterlingService.Current.Database.Query
                        &amp;lt;FoodDescription, string, int, int&gt;(
                            FoodDatabase.FOOD_DESCRIPTION_DESC_GROUP)
                    where
                        fg.Index.Item2.Equals(_currentGroup.Id) &amp;&amp;
                        fg.Index.Item1.ToUpperInvariant().Contains(_searchText.ToUpperInvariant())
                    select
                        new FoodDescriptionIndex {Id = fg.Key, Description = fg.Index.Item1};
                        
            return query2.Count() == 0 ? _noResults.AsEnumerable() : query2;
        }

        if (string.IsNullOrEmpty(_searchText) || _searchText.Length &lt; 3)
            return _noResults.AsEnumerable();

        var query3 = from fg in
                    SterlingService.Current.Database.Query
                    &amp;lt;FoodDescription, string, int, int&gt;(
                        FoodDatabase.FOOD_DESCRIPTION_DESC_GROUP)
                where
                    fg.Index.Item1.ToUpperInvariant().Contains(_searchText.ToUpperInvariant())
                select
                    new FoodDescriptionIndex { Id = fg.Key, Description = fg.Index.Item1 };
        return query3.Count() == 0 ? _noResults.AsEnumerable() : query3; 
    }
}
&lt;/pre&gt;
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=271&amp;g2_serialNumber=1" alt="Food items" title="Food items"/&gt;
&lt;p&gt;Notice how I'm using a "covered index" (covered for the items I need, which include the key and description) to query and return a list of types that are bound to the list box. You can see when you run the example this happens very fast. Finally, when you click on the item, I am always deserializing rather than trying to cache a ton of objects.
&lt;p&gt;The food description context class synchronizes the current food item between view models. Notice when it is passed a value, it loads the new item: 
&lt;pre class="brush: csharp;"&gt;
public class FoodDescriptionContext : BaseNotify 
{
    public static FoodDescriptionContext Current = new FoodDescriptionContext();

    public FoodDescription CurrentFoodDescription { get; private set; }

    private int _foodDescriptionId; 

    public int FoodDescriptionId
    {
        get { return _foodDescriptionId; }
        set
        {
            _foodDescriptionId = value;
            CurrentFoodDescription = SterlingService.Current.Database.Load&amp;lt;FoodDescription&gt;(value);
            RaisePropertyChanged(()=&gt;CurrentFoodDescription);
            RaisePropertyChanged(()=&gt;FoodDescriptionId);
        }
    }

}
&lt;/pre&gt;
&lt;p&gt;This isn't thread-safe, but does it need to be? The user can only click on one item at a time. 
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=263&amp;g2_serialNumber=2" alt="Food detail" title="Food detail"/&gt;
&lt;p&gt;Finally, the whole engine is configured using an application service.
&lt;p&gt;There's a lot more to it but I wanted to get this out there and have people start looking at it to provide me with feedback. While there is not yet a release, you can visit the &lt;a href="http://sterling.codeplex.com/" target="_blank"&gt;Sterling Codeplex site&lt;/a&gt; to download the code (pre-alpha, so use at your own risk, right?) and build/test/integrate on your own. Let me know what you like and don't like and if you are interested in being a serious beta tester, and we'll see what we can do to release a solid version 1. 
&lt;p&gt;(PS, I took a simple list project for the Windows Phone 7 just to prove the engine works there - I simply save the list to the database then bind to the query - but I'm looking for a more comprehensive example there, so volunteers are welcome to work on that as well!) 
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-6309667385178641205?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://sterling.codeplex.com/' title='Introducing Sterling, the Object-Oriented Database for Silverlight and Windows Phone 7'/><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/6309667385178641205/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/introducing-sterling-object-oriented.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/6309667385178641205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/6309667385178641205'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/introducing-sterling-object-oriented.html' title='Introducing Sterling, the Object-Oriented Database for Silverlight and Windows Phone 7'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-7862297362669278672</id><published>2010-03-17T08:36:00.003-04:00</published><updated>2010-07-02T11:16:15.425-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='viewmodel'/><category scheme='http://www.blogger.com/atom/ns#' term='Managed Extensibility Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='mvvm'/><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><title type='text'>ViewModel binding with the Managed Extensibility Framework</title><content type='html'>&lt;p&gt;This is just a short post to share an "ah-hah" moment I experienced building out a large Managed Extensibility Framework (MEF) Silverlight application. Traditionally, I've wired in the view models using the code behind. I'm not one of those who believes code behind is evil no matter what, so I haven't taken issue with something like this: 
&lt;pre class="brush: csharp;"&gt;
[Import] 
public MainViewModel ViewModel 
{
   get { return LayoutRoot.DataContext as MainViewModel; }
   set { LayoutRoot.DataContext = value; }
}
&lt;/pre&gt;
&lt;p&gt;This simply imports the view model that I need and then passes it along to the data context. The issue with XAML is that it doesn't allow me to pass in constructor information and always creates a "new" instance, so if the view model is part of a larger dependency chain, I'd get a new instance in every page that needed a copy. 
&lt;p&gt;This is an example of when having design patterns as a part of your vocabulary can improve your ability to solve problems. Obviously, it wasn't part of my vocabulary or I wouldn't have missed it! There is a nice pattern that neatly addresses the concern of having a view model wired in by MEF that allows for attaching it in XAML without having to use code behind. Again, I'm not opposed to code behind, but any time I can abstract the behavior further and do it in a natural way without jumping through hoops just to make it work is something I'll consider.
&lt;p&gt;Enter the &lt;a href="http://msdn.microsoft.com/en-us/library/cc707905.aspx" target="_blank"&gt;Service Locator&lt;/a&gt; design pattern. The challenge is that you have components that are based on service contracts and the concrete implementation not known at design time. In our case, the "service" is the view model, and it's not concrete yet because we haven't composed the parts. 
&lt;p&gt;Let's create our service locator for view models. In this example, I only have one, but in the application I am working on there are several, and they all get exposed via the service locator: 
&lt;pre class="brush: csharp;"&gt;
public class ViewModelLocator 
{
   public ViewModelLocator()
   {
      CompositionInitializer.SatisfyImports(this);
   }
  
   [Import]
   public MainViewModel MainViewModelInstance { get; set; }
}
&lt;/pre&gt; 
&lt;p&gt;It's that simple. The class itself composes the view model for us, then provides a property we can use to access the view model. Because we are importing via MEF, we can control the lifetime for the view model and any other attributes we need to compose it properly. Now, we can wire in the view model with no code behind. The XAML looks like this: 
&lt;pre class="brush: xml;"&gt;
&amp;lt;UserControl ... xmlns:vm="clr-namespace:ViewModel"&gt;
&amp;lt;UserControl.Resources&gt;
   &amp;lt;vm:ViewModelLocator x:Key="VMLocator"/&gt;
&amp;lt;/UserControl.Resources&gt;
&amp;lt;Grid
   x:Name="LayoutRoot"
   DataContext={Binding Source={StaticResource VMLocator},Path=MainViewModelInstance}"&gt;
   ...
&amp;lt;/Grid&gt;
&lt;/pre&gt;
&lt;p&gt;There you have it ... a simple, clean way to bind the view model to the view without code behind and still allow MEF to compose all of the parts for you.
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-7862297362669278672?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/7862297362669278672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/03/viewmodel-binding-with-managed.html#comment-form' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/7862297362669278672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/7862297362669278672'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/03/viewmodel-binding-with-managed.html' title='ViewModel binding with the Managed Extensibility Framework'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-3538875956704622646</id><published>2010-07-01T08:56:00.006-04:00</published><updated>2010-07-01T22:52:45.677-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight 4'/><category scheme='http://www.blogger.com/atom/ns#' term='windows phone 7 series'/><category scheme='http://www.blogger.com/atom/ns#' term='sterling'/><category scheme='http://www.blogger.com/atom/ns#' term='iapplicationservice'/><title type='text'>Customer IApplicationService for Silverlight Applications</title><content type='html'>&lt;p&gt;In my experience working with Silverlight applications, probably one of the most underused features I've witnessed is the ability to abstract application-level functionality using the &lt;code&gt;IApplicationService&lt;/code&gt; and &lt;code&gt;IApplicationLifetimeAware&lt;/code&gt; interfaces. This, in turn, results in the over-use (and abuse) of the &lt;code&gt;Startup&lt;/code&gt; and &lt;code&gt;Exit&lt;/code&gt; events in the &lt;code&gt;Application&lt;/code&gt; object. Before you get angry with me shaking a finger, I'll admit I've done this quite a bit myself.
&lt;p&gt;&lt;b&gt;IApplicationService&lt;/b&gt;
&lt;p&gt;The &lt;code&gt;IApplicationService&lt;/code&gt; interface allows you to define a class that is part of the overall application lifecycle. It provides a mechanism to create a service that lasts the duration of a Silverlight application. It is called once when the application starts with an &lt;code&gt;ApplicationServiceContext&lt;/code&gt;, and called again when the application ends.
&lt;p&gt;One of the most useful things you can do with this service class is use it to intelligently parse parameters passed to the Silverlight application. How many times have you found yourself hooking into the application startup and then parsing these out? What's worse, in larger, complex applications, many different portions of the application share responsibility for handling these parameters. It breaks the concept of loose coupling to have a single front-end parsing it out and then stuffing it into an object to dole it out to the consumers that need it.
&lt;p&gt;By implementing &lt;code&gt;IApplicationService&lt;/code&gt;, you can create a service for your functionality that handles its own initialization parameters. There is no "central" place that has to understand everything. Silverlight supports using multiple application services, so you can have a logger service that looks at the logging parameter and a file upload service that looks at the file storage location parameter, so on and so forth. 
&lt;p&gt;Here's what a service that handles writing to the debugger might look like:
&lt;pre class="brush: csharp;"&gt;
public class LoggerService : IApplicationService
{
    const string TRACE_LEVEL_KEY = "TraceLevel";
            
    public LoggerService()
    {
        _traceLevel = TraceLevel.Warning; // default
    }
   
    private TraceLevel _traceLevel; 

    public ILogger Logger { get; private set; }
        
    public static LoggerService Current { get; private set; }

    public void StartService(ApplicationServiceContext context)
    {
        Current = this;
        if (context.ApplicationInitParams.ContainsKey(TRACE_LEVEL_KEY))
        {
            _traceLevel = (TraceLevel)Enum.Parse(typeof (TraceLevel), context.ApplicationInitParams[TRACE_LEVEL_KEY], true);
        }

        Logger = new CustomLogger(TraceLevel);
        Logger.WriteLine(TraceLevel.Information, "Logger service started.");
    }

    public void StopService()
    {
        Logger.WriteLine(TraceLevel.Information, "Logger service stopped.");
    }
}
&lt;/pre&gt;
&lt;p&gt;This service now allows me to configure the logging level in the web page using &lt;code&gt;initParams&lt;/code&gt;, like this: 
&lt;pre class="brush: html;"&gt;
&amp;lt;object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"&gt;
   &amp;lt;param name="source" value="ClientBin/MySilverlightApp.xap"/&gt;
   &amp;lt;param name="onError" value="onSilverlightError" /&gt;
   &amp;lt;param name="initParams" value="TraceLevel=Warning" /&gt;
   &amp;lt;param name="background" value="white" /&gt;
   &amp;lt;param name="minRuntimeVersion" value="4.0.50401.0" /&gt;
   &amp;lt;param name="autoUpgrade" value="true" /&gt;    
&amp;lt;/object&gt;
&lt;/pre&gt;
&lt;p&gt;What's more, if it is in a project by itself, adding the service to a new application is so simple it's hard to believe more people don't take advantage of this. After referencing the project, I won't have to mangle my &lt;code&gt;App.xaml.cs&lt;/code&gt; and hook into any events in order to use the new service, parse out parameters, etc. Nope, I just add a simple reference to it in the &lt;code&gt;App.xaml&lt;/code&gt; that looks like this:
&lt;pre class="brush: xml;"&gt;
&amp;lt;Application.ApplicationLifetimeObjects&gt;
    &amp;lt;MySilverlightApp:LoggerService/&gt;
&amp;lt;/Application.ApplicationLifetimeObjects&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;IApplicationLifetimeAware&lt;/b&gt;
&lt;p&gt;Now, if you really want to do some cool things, you can extend the class even further by implementing &lt;code&gt;IApplicationLifetimeAware&lt;/code&gt;. This will give you four additional methods: &lt;code&gt;Starting&lt;/code&gt;, &lt;code&gt;Started&lt;/code&gt;, &lt;code&gt;Exiting&lt;/code&gt;, and &lt;code&gt;Exiting&lt;/code&gt;.
&lt;p&gt;Use these to perform set up and clean up actions.
&lt;p&gt;For example, in the &lt;a href="http://sterling.codeplex.com/" target="_blank"&gt;Sterling Windows Phone 7 Example&lt;/a&gt; I wrote (Sterling is an open source object-oriented database for Silverlight 4.0 and Windows Phone 7) I created a database service to make it easy to set up and tear down the database engine. The service looks like this: 
&lt;pre class="brush: csharp;"&gt;
public class DatabaseService : IApplicationService, IApplicationLifetimeAware
{
    public static DatabaseService Current { get; private set; }

    public ISterlingDatabaseInstance Database { get; private set; }

    private SterlingEngine _engine;
        
    public void StartService(ApplicationServiceContext context)
    {
            
        Current = this;
        _engine = new SterlingEngine();
    }

    public void StopService()
    {
        _engine = null;
    }

    public void Starting()
    {
        _engine.Activate();
        Database = _engine.SterlingDatabase.RegisterDatabase&amp;lt;PhoneDatabase&gt;();
    }

    public void Started()
    {
        return;
    }

    public void Exiting()
    {
        _engine.Dispose();
    }

    public void Exited()
    {
        return;
    }
}
&lt;/pre&gt;
&lt;p&gt;As you can see, I am managing everything that would normally get hooked into the application startup and exit events. Instead of adding to that code-behind, however, I can abstract these hooks in a re-usable component that is easily dropped into or out of the &lt;code&gt;App.xaml&lt;/code&gt; as needed. Just like the previous example, the only thing needed to hook into the database in a Windows Phone 7 application is now just this: 
&lt;pre class="brush: xml;"&gt;
&amp;lt;Application.ApplicationLifetimeObjects&gt;
   &amp;lt;SterlingExample:SterlingService/&gt;
&amp;lt;/Application.ApplicationLifetimeObjects&gt;
&lt;/pre&gt;
&lt;p&gt;The Silverlight framework guarantees my service is called to start only once, so I take advantage of that call to assign a static property. That way, anywhere in the application I need to reference the service, I can use ServiceName.Current (for example, SterlingService.Current). 
&lt;p&gt;Don't limit yourself to just that, however. One common task in composite Silverlight applications is "bootstrapping" objects. If you are using the Managed Extensibility Framework (MEF), you may need to configure some catalogs and then call the &lt;code&gt;CompositionInitializer&lt;/code&gt;. You can do this in an application service as well. In fact, many of my applications have nothing in the &lt;code&gt;App.xaml.cs&lt;/code&gt; code behind except a call to &lt;code&gt;InitializeComponent&lt;/code&gt;. Why? Because I can set the root visual in a service, like this: 
&lt;pre class="brush: csharp;"&gt;

[Import]
public Shell MainShell { get; set; }

public void StartService(ApplicationServiceContext context)
{
    _myCatalog = new AggregateCatalog(new DeploymentCatalog()); 
    var container = new CompositionContainer(_mainCatalog);
    CompositionHost.Initialize(container);              
    CompositionInitializer.SatisfyImports(this);
}

public void Starting()
{
    Application.Current.RootVisual = MainShell;
}

&lt;/pre&gt;
&lt;p&gt;When called, the service sets up the catalogs/containers/etc. and satisfies imports to generate the shell. If the shell has any dependencies, these are also handled by MEF. Then, in the starting method, we wire the shell to the root visual because this is called just before the full visual tree is loaded.
&lt;p&gt;I hope to see this powerful feature used more often to add some quality customer service to Silverlight applications.
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-3538875956704622646?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/3538875956704622646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/customer-iapplicationservice-for.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/3538875956704622646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/3538875956704622646'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/07/customer-iapplicationservice-for.html' title='Customer IApplicationService for Silverlight Applications'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-1080375468758130302</id><published>2010-05-14T12:13:00.003-04:00</published><updated>2010-06-29T09:35:07.520-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Managed Extensibility Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight 4'/><category scheme='http://www.blogger.com/atom/ns#' term='deploymentcatalog'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamic modules'/><title type='text'>WebClient and DeploymentCatalog gotchas in Silverlight OOB</title><content type='html'>&lt;p&gt;This is a quick post to share a gotcha I found that may be impacting others. 
&lt;p&gt;I am in the process of building a large composable application for a customer using Silverlight 4 and the Managed Extensibility Framework (MEF). The application has a framework that supports multiple line of business applications that are dynamically loaded and registered to the main application. 
&lt;p&gt;This application works both in browser and out-of-browser and even in offline mode. The DeploymentCatalog in MEF works with the web client stack underneath the hood, so it functions the same way as if you tried to request the files yourself and then pull them down. If online, it will request from the web, otherwise it will look to cache. If the cache is empty, you're stuck.
&lt;p&gt;The first caveat with working out of browser is that relative urls no longer work. They are relative to your install base so they will not find the XAP. There are a few ways to resolve this, but the easiest I've found is to sense when running online (i.e. the first time it is launched) and save the URI to IsolatedStorageSettings. Then, in offline mode, you can pull it out and reconstruct the URI back to the place the host XAP was located, and specify a fully qualified URI:
&lt;pre class="brush: csharp;"&gt;
if (Current.IsRunningOutOfBrowser)
{
    Source = IsolatedStorageSettings.ApplicationSettings[SOURCEURI] as Uri;
}
else
{
    var src = Current.Host.Source.ToString();
    src = src.Substring(0, src.LastIndexOf('/')+1);
    Source = new Uri(src);
    IsolatedStorageSettings.ApplicationSettings[SOURCEURI] = Source;
    IsolatedStorageSettings.ApplicationSettings.Save();
}
&lt;/pre&gt;
&lt;p&gt;Now you can easily make a full URI like this: 
&lt;p&gt;&lt;code&gt;var uri = new Uri(Source, "local.xap");&lt;/code&gt;
&lt;p&gt;After that point it is mostly business as usual, unless you run into a problem like I did. My application was working perfectly in the browser, but in OOB mode it would not load. I started debugging and found that all of my WebClient and DeploymentCatalog downloads would fire ... but then nothing would happen. They'd never return, not even with an error. 
&lt;p&gt;This was very puzzling to me and I researched it far and wide and could not find a resolution. I made a sample side project as a proof of concept and everything worked fine. What was different?
&lt;p&gt;I actually reached out to my team for help when it hit me ... something a little "different" I was doing. 
&lt;p&gt;The &lt;code&gt;App.cs&lt;/code&gt; typically sets the &lt;code&gt;RootVisual&lt;/code&gt; of your application. You might create a new control and set it or use composition to import it. Because I had multiple modules to load, I wanted to delay setting the root visual until everything was loaded. So, I created a special loader class to do this, and held off on assigning the root visual until composition was complete.
&lt;p&gt;It turns out this was the culprit. While it worked fine in the web browser, something in OOB was expecting the root visual to be set. When I set it to an empty grid, everything suddenly worked fine. So, I put the empty grid in place and then add the composed control as a child of the grid when composition finishes.
&lt;p&gt;We were going to add this anyway (to provide a nice status to the user as the parts were being initialized) but I never suspected it would kill my ability to do anything on the network. If you have experienced similar quirkiness in your applications, this may be one place to look.
&lt;p&gt;A colleague believes it may be due to the fact that WebClient and DeploymentCatalog (via web client) both return via Dispatcher, and with no root visual, there may be no dispatcher to latch to ... sounds plausible to me. 
&lt;p&gt;Also wanted to share that a case study for an important Silverlight project was officially released by Microsoft: 
&lt;p&gt;&lt;b&gt;Vancouver Winter Olympics Case Featuring Wintellect's Works with Microsoft and NBC&lt;/b&gt;
&lt;p&gt;Learn about Wintellect's work with Microsoft and NBC/CTV to support real time video for the 2010 Vancouver Winter Olympics video site using Smooth Streaming and Silverlight. Read the recently released case study and learn about the massive effort across multiple partners to pull together the on-line solution for streaming HD videos, both live and on demand for the Vancouver Winter Olympics. Get an inside view of Wintellect's contribution to making this project a success with coverage of 360 events,  4.4 million hours of video, and much more!
&lt;p&gt;Here is the link: &lt;A href="http://www.microsoft.com/casestudies/Case_Study_Detail.aspx?casestudyid=4000007258" target="_blank"&gt;Winter Olympics Case Study&lt;/a&gt;
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-1080375468758130302?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/1080375468758130302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/05/webclient-and-deploymentcatalog-gotchas.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/1080375468758130302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/1080375468758130302'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/05/webclient-and-deploymentcatalog-gotchas.html' title='WebClient and DeploymentCatalog gotchas in Silverlight OOB'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-3198715277064593971</id><published>2010-06-09T06:06:00.003-04:00</published><updated>2010-06-29T09:34:26.612-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Managed Extensibility Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight 4'/><category scheme='http://www.blogger.com/atom/ns#' term='line of business'/><title type='text'>Managed Extensibility Framework for Line of Business Applications in .NET 4.0</title><content type='html'>&lt;p&gt;I recently gave a talk for the &lt;a href="http://atlantamspros.com/default.aspx" target="_blank"&gt;Atlanta Microsoft Professionals&lt;/a&gt; users group about using the Managed Extensibility Framework for Line of Business applications in .NET 4.0. We had a great turnout and I appreciate everyone who attended. The talk was based on my blog post "&lt;a href="http://csharperimage.jeremylikness.com/2010/04/ten-reasons-to-use-managed.html" target="_blank"&gt;10 Reasons to use the Managed Extensibility Framework&lt;/a&gt;." 
&lt;p&gt;While the talk itself wasn't recorded, I'm happy to share the slide deck with you. You can &lt;a href="http://www.wintellect.com/CS/files/folders/sample_files/entry15083.aspx" target"_blank"&gt;download it here&lt;/a&gt; and watch the presentation for yourself. I covered not only the benefits of using MEF, but touched on some of the costs associated with it as well.
&lt;p&gt;This is the abstract for the talk: 
&lt;p&gt;With the release of Visual Studio 2010, the Managed Extensibility Framework (MEF) became a first-class citizen of the .NET 4.0 Framework. It is the same system used for extensibility and plug-ins within Visual Studio 2010 itself. Learn the ten reasons why you would want to use the Managed Extensibility Framework in your own applications and how MEF can assist you with building dynamic, modular, extensible, testable applications faster than ever before. This deep dive will cover advanced MEF topics included strongly typed meta-data and custom export providers as well as how MEF differs between Web, WPF, Console, and Silverlight applications.
&lt;p&gt;Enjoy the &lt;a href="http://www.wintellect.com/CS/files/folders/sample_files/entry15083.aspx" target="_blank"&gt;presentation&lt;/a&gt;! 
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-3198715277064593971?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.wintellect.com/CS/files/folders/sample_files/entry15083.aspx' title='Managed Extensibility Framework for Line of Business Applications in .NET 4.0'/><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/3198715277064593971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/06/managed-extensibility-framework-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/3198715277064593971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/3198715277064593971'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/06/managed-extensibility-framework-for.html' title='Managed Extensibility Framework for Line of Business Applications in .NET 4.0'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-1479445653804109198</id><published>2010-06-10T11:55:00.006-04:00</published><updated>2010-06-29T09:34:06.946-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvvm'/><category scheme='http://www.blogger.com/atom/ns#' term='inotifypropertychanged'/><title type='text'>Tips and Tricks for INotifyPropertyChanged</title><content type='html'>&lt;p&gt;As a WPF or Silverlight developer, you know that your models must implement &lt;code&gt;INotifyPropertyChanged&lt;/code&gt; and it can be a pain. To do it safely, you really need to check to see if there are any registered handlers, then raise the event. To add insult to injury, the event arguments take a string, so if you mistype the property name you're out of luck. Some clever individuals have created nice code snippets to generate the needed plumbing, but it doesn't help with refactoring.
&lt;p&gt;One common solution is to create a base class that provides the plumbing for a raise property notification. 
&lt;p&gt;The first &lt;a href="http://compositewpf.codeplex.com/" target="_blank"&gt;Prism 4.0 drop&lt;/a&gt; has a typical example of this, and one that mirrors what I've done in quite a few places. Take a look at some snippets from the base view model designed in the &lt;a href="http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html" target="_blank"&gt;Model-View-ViewModel (MVVM)&lt;/a&gt; quick start:
&lt;pre class="brush: csharp;"&gt;
        protected virtual void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        protected void RaisePropertyChanged(params string[] propertyNames)
        {
            foreach (var name in propertyNames)
            {
                this.RaisePropertyChanged(name);
            }
        }

        protected void RaisePropertyChanged&amp;lt;T&gt;(Expression&amp;lt;Func&amp;lt;T&gt;&gt; propertyExpresssion)
        {
            var propertyName = ExtractPropertyName(propertyExpresssion);
            this.RaisePropertyChanged(propertyName);
        }

        private string ExtractPropertyName&amp;lt;T&gt;(Expression&amp;lt;Func&amp;lt;T&gt;&gt; propertyExpresssion)
        {
            if (propertyExpresssion == null)
            {
                throw new ArgumentNullException("propertyExpression");
            }

            var memberExpression = propertyExpresssion.Body as MemberExpression;
            if (memberExpression == null)
            {
                throw new ArgumentException("The expression is not a member access expression.", "propertyExpression");
            }

            var property = memberExpression.Member as PropertyInfo;
            if (property == null)
            {
                throw new ArgumentException("The member access expression does not access a property.", "propertyExpression");
            }

            if (!property.DeclaringType.IsAssignableFrom(this.GetType()))
            {
                throw new ArgumentException("The referenced property belongs to a different type.", "propertyExpression");
            }

            var getMethod = property.GetGetMethod(true);
            if (getMethod == null)
            {
                // this shouldn't happen - the expression would reject the property before reaching this far
                throw new ArgumentException("The referenced property does not have a get method.", "propertyExpression");
            }

            if (getMethod.IsStatic)
            {
                throw new ArgumentException("The referenced property is a static property.", "propertyExpression");
            }

            return memberExpression.Member.Name;
        }
    }
&lt;/pre&gt;
&lt;p&gt;The piece that extracts the expression is key, because it allows you to get away from &lt;code&gt;RaisePropertyChanged("property")&lt;/code&gt; and move to the more strongly-typed and refactoring-friendly &lt;code&gt;RaisePropertyChanged(()=&gt;property)&lt;/code&gt;.
&lt;p&gt;The base class might work well for some, but putting too much functionality in the base class can sometimes become a problem. The main reason is due to the fact that there is not multiple inheritance, therefore if you have multiple functions that are aspects of some classes and not others, you either need to create a grab bag of different derived classes, or drag along the functionality you don't need.
&lt;p&gt;Fortunately, extension methods allow us to have the best of both worlds. We can simply extend the behavior as it is defined, via the &lt;code&gt;INotifyPropertyChanged&lt;/code&gt; interface, and then implement it with an extension.
&lt;p&gt;Take a look at the property helper class: 
&lt;pre class="brush: csharp;"&gt;
public static class PropertyHelper
{        
    public static string ExtractPropertyName&amp;lt;T&gt;(Expression&amp;lt;Func&amp;lt;T&gt;&gt; propertyExpression)
    {
        if (propertyExpression == null)
        {
            throw new ArgumentNullException("propertyExpression");
        }

        var memberExpression = propertyExpression.Body as MemberExpression;

        if (memberExpression == null)
        {
            throw new ArgumentException("The expression is not a member access expression.", "propertyExpression");
        }

        var property = memberExpression.Member as PropertyInfo;

        if (property == null)
        {
            throw new ArgumentException("The member access expression does not access a property.", "propertyExpression");
        }
            
        return memberExpression.Member.Name;
    }

    public static void RaisePropertyChanged&amp;lt;T&gt;(this INotifyPropertyChanged src, Expression&amp;lt;Func&amp;lt;T&gt;&gt; propertyExpression, PropertyChangedEventHandler handler)
    {
        if (handler != null)
        {
            handler(src, new PropertyChangedEventArgs(ExtractPropertyName(propertyExpression)));
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;Notice how we extend the interface and simply take in the property expression and the handler. Now, I can raise the property like this: 
&lt;pre class="brush: csharp;"&gt;
private string _myProperty;

public string MyProperty 
{
   get 
   {
      return _myProperty;
   }

   set 
   {
      _myProperty = value;
      this.RaisePropertyChanged(()=&gt;MyProperty, PropertyChangedHandler); 
   }
}
&lt;/pre&gt;
&lt;p&gt;Of course, you don't even have to make it an extension method at all - it could simply be a helper you call directly. 
&lt;p&gt;There is only one problem with this implementation, that I would be remiss if I didn't call out. In a typical system you're probably fine, but you are taking something internal to the class (the change handler) and sending it out in the wild. Something outside of your class could then manipulate or hook into the handler (as we are doing, on purpose, for the property event) and cause unexpected behaviors and results. If you can live with that caveat and it helps, then here is one more way to handle the pattern.
&lt;p&gt;&lt;b&gt;Bonus Round: Observable Enumerables&lt;/b&gt;
&lt;p&gt;Oh, one more thing. Have you found you often bind things like charts, lists, and grids to lists where the &lt;i&gt;entire list changes&lt;/i&gt;? In other words, you are never adding or removing individual items, but instead clearing your &lt;code&gt;ObservableCollection&lt;/code&gt; and re-adding them? Depending on how you do that, it can be a costly operation as the &lt;code&gt;CollectionChanged&lt;/code&gt; will fire for each item. But ... assigning a new list will suddenly kill your data-binding, because the controls lose their reference to the list (the original binding).
&lt;p&gt;Solution? 
&lt;p&gt;Expose an &lt;code&gt;IEnumerable&amp;lt;T&gt;&lt;/code&gt; that contains whatever logic you need to build the list - whether it is the return from a service call, spinning up a new list, etc. Then, whenever you have a condition that changes the list (i.e. a new search term, filter property, refresh command, etc) simply raise the property changed event for that list.
&lt;p&gt;It will end up looking something like this:
&lt;pre class="brush: csharp;"&gt;
public class MyViewModel : INotifyPropertyChanged 
{
   public IParameters Parameters { get; set; }

   public IService Service { get; set; }

   private List&amp;lt;Widget&gt; _widgets; 

   public MyViewModel()
   {
      // this code may go somewhere else depending on how you wire up dependencies
      Parameters.PropertyChanged += (o,e) =&gt; _NewQuery;
      Service.QueryAsyncCompleted += (o,e) =&gt; 
      {
         _widgets = e.Result; 
         RaisePropertyChanged(()=&gt;TopFiveQuery, PropertyChanged);
         RaisePropertyChanged(()=&gt;Query, PropertyChanged);
      }
   }

   private void _NewQuery()
   {
      Service.QueryAsync(Parameters);
   }
   
   public IEnumerable&amp;lt;Widget&gt; TopFiveQuery
   {
       return (from w in _widgets orderby w.DateModified descending 
               select w).Take(5).AsEnumerable();
   }

   public IEnumerable&amp;lt;Widget&gt; Query
   {
       return _widgets;   
   }

   public event PropertyChangedEventHandler PropertyChanged;
}
&lt;/pre&gt;
&lt;p&gt;Now a control can be bound to the Query directly. Whenever the user changes parameters, it fires a property changed event that calls out to the service. When the service returns, it loads up the results and then fires the property changed for the list, which rebinds the list to the control. The reason I show it this way is you might reuse the data in different lists and have different filters. By exposing the enumerable interface, you can provide multiple queries and have them all update and re-bind on the single service call. 
&lt;p&gt;Enjoy!
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-1479445653804109198?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/1479445653804109198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/06/tips-and-tricks-for-inotifypropertychan.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/1479445653804109198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/1479445653804109198'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/06/tips-and-tricks-for-inotifypropertychan.html' title='Tips and Tricks for INotifyPropertyChanged'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-7134562443780006498</id><published>2010-06-29T09:06:00.003-04:00</published><updated>2010-06-29T09:33:49.005-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight unit test'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamic modules'/><title type='text'>Unit Testing Dynamic XAP Files</title><content type='html'>&lt;p&gt;By now, you probably are aware that you can dynamically load XAP files using the Managed Extensibility Framework (MEF) within your Silverlight applications. Have you been scratching your head, however, and wondering how on earth you would actually test something like that? 
&lt;p&gt;It is possible, and here's a quick post to show one way you can.
&lt;p&gt;First, we need a decent deployment service. You're not really going to hard-code the download and management, are you? I didn't think so. If you need an example, look no further than the sample code I posted to &lt;a href="http://csharperimage.jeremylikness.com/2010/06/advanced-silverlight-applications-using.html" target="_blank"&gt;Advanced Silverlight Applications using MEF&lt;/a&gt;. Here's what the interface looks like:
&lt;pre class="brush: csharp;"&gt;
public interface IDeploymentService
{
    void RequestXap(string xapName, Action&amp;lt;Exception&gt; xapLoaded);       
       
    AggregateCatalog Catalog { get; }
}
&lt;/pre&gt;
&lt;p&gt;This keeps it simple. Request the xap file, then specify a delegate for a callback. You'll either get a null exception object (it was successful) or a non-null (uh... oh.) 
&lt;p&gt;Now, let's focus on testing it using the &lt;a href="http://code.msdn.microsoft.com/silverlightut" target="_blank"&gt;Silverlight Unit Testing Framework&lt;/a&gt;. The first caveat is that you cannot use it on the file system. This means that your project will not work if you run it with a test page rather than hooking it to a web server (local or not). 
&lt;p&gt;Doing this is simple. In your ASP.NET project, go to the Silverlight tab and add your test project. When you are adding it, there is an option to generate a test page. I typically have one "test" web project with all of my test Silverlight applications, so I will have multiple test pages. To run a particular test, you simply set your ASP.NET web project as the start up project, then the corresponding test page (we're talking the aspx, not the html) as the start page. I usually delete the automatically generated HTML pages.
&lt;p&gt;Now we need to give MEF a test container. The caveat here is that, without a lot of work, it's not straightforward to reconfigure the host container so you'll want to make sure you test a given dynamic XAP file only once, because once it's loaded, it's loaded.
&lt;p&gt;This is what my application object ends up looking like:
&lt;pre class="brush: csharp;"&gt;
public partial class App
{
    public AggregateCatalog TestCatalog { get; private set; }

    public App()
    {
        Startup += Application_Startup;            
        InitializeComponent();
    }

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        // set up a catalog for tests
        TestCatalog = new AggregateCatalog();
        TestCatalog.Catalogs.Add(new DeploymentCatalog());

        var container = new CompositionContainer(TestCatalog);

        CompositionHost.Initialize(container);

        // now set up the unit testing framework
        var settings = UnitTestSystem.CreateDefaultSettings();
        RootVisual = UnitTestSystem.CreateTestPage(settings);
    }              
}
&lt;/pre&gt;
&lt;p&gt;Here, I haven't composed anything, just set up the container. 
&lt;p&gt;Now I'm going to add a simple dynamic XAP for testing. I add a new Silverlight application and wire it to the test web site but do NOT generate a test page. I blow away the App.xaml and MainPage.xaml resources, and add a simple class called &lt;code&gt;Exports&lt;/code&gt;. Here is my class:
&lt;pre class="brush: csharp;"&gt;
public class Exports
{
    private const string TESTTEXT = "TestText";

    [Export(TESTTEXT, typeof(string))]
    public string TestText { get { return TESTTEXT; } }
}
&lt;/pre&gt;
&lt;p&gt;Yes, you got it - just a simple export of a string value. Now let's write our test. I create a new test class and decorate it with the &lt;code&gt;TestClass&lt;/code&gt; attribute. I am also running asynchronous tests, so it's best to inherit the test from &lt;code&gt;SilverlightTest&lt;/code&gt; which has some base methods for asynchronous testing. 
&lt;p&gt;Let's take a look at the set up for my test:
&lt;pre class="brush: csharp;"&gt;
[TestClass]
    public class DeploymentServiceTest : SilverlightTest
    {
        private const string DYNAMIC_XAP = "DynamicXap.xap";
        private const string TESTTEXT = "TestText";

        private DeploymentService _target;
    
        [Import(TESTTEXT, AllowDefault = true, AllowRecomposition = true)]
        public string TestString { get; set; }
     
        public DeploymentServiceTest()
        {
            CompositionInitializer.SatisfyImports(this);
        }

        [TestInitialize]
        public void TestInit()
        {
            if (Application.Current.Host.Source.Scheme.Contains("file"))
            {
                _target = null;
            }
            else
            {
                _target = new DeploymentService();
                ((App) Application.Current).TestCatalog.Catalogs.Add(_target.Catalog);
            }
        }
}
&lt;/pre&gt;
&lt;p&gt;So right now I'm simply setting up my targets. The property is key - by composing imports on construction, I register my test class with the MEF system. Right now, however, I haven't loaded anything, so it won't be able to satisfy the import. By using &lt;code&gt;AllowDefault&lt;/code&gt; true, however, I tell it I'm expecting something later and setting it to null is fine. The recomposition is what will trigger an update once the catalogs change. I also reach out to the test catalog I set up in the main application and add the catalog from my deployment service to it. Note that if I am running on the file system, I don't bother setting up my service.
&lt;p&gt;Next, I can add a stub to determine if I can even test this. If I am running from the file system, the deployment service is never set up. I created a helpful method that asserts an "inconclusive" when this is the case:
&lt;pre class="brush: csharp;"&gt;
private bool _CheckWeb()
{
    if (_target == null)
    {
        Assert.Inconclusive("Cannot test deployment service from a test page. Must be hosted in web.");
        return false;
    }

    return true;
}        
&lt;/pre&gt; 
&lt;p&gt;Now we can write our main test. First, we check to make sure we are in a web context. Then, we load the xap, and once it is loaded, confirm there were no errors and that our property was successfully set:
&lt;pre class="brush: csharp;"&gt;
[Asynchronous]
[TestMethod]
public void TestValidXap()
{
    if (!_CheckWeb())
    {
        return;
    }

    Assert.IsTrue(string.IsNullOrEmpty(TestString), "Test string should be null or empty at start of test.");
    _target.RequestXap(DYNAMIC_XAP, exception =&gt;
                                        {
                                            Assert.IsNull(exception, "Test failed: exception returned.");
                                            Assert.IsFalse(string.IsNullOrEmpty(TestString),
                                                            "Test failed: string was not populated.");
                                            Assert.AreEqual(TESTTEXT, TestString,
                                                            "Test failed: property does not match.");
            }
}
&lt;/pre&gt;
&lt;p&gt;And that's pretty much all there is to it - of course, I am also adding checks for things like contract validation (are you passing me a valid xap name?) and managing duplicates, but you get the picture.
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-7134562443780006498?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/7134562443780006498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/06/unit-testing-dynamic-xap-files.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/7134562443780006498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/7134562443780006498'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/06/unit-testing-dynamic-xap-files.html' title='Unit Testing Dynamic XAP Files'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-8283329341817396070</id><published>2010-06-26T13:25:00.005-04:00</published><updated>2010-06-26T13:46:25.306-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='codestock'/><title type='text'>Advanced Silverlight Applications using the Managed Extensibility Framework</title><content type='html'>&lt;p&gt;This week I had the pleasure of attending my first &lt;a href="http://www.codestock.org/" target="_blank"&gt;CodeStock event&lt;/a&gt; in Knoxville, TN. Let me start by saying it was an amazing event. I give many thanks to the attendees, for keeping it a strong and thriving community, the sponsors (including my company, &lt;a href="http://www.wintellect.com/" target="_blank"&gt;Wintellect&lt;/a&gt;), the speakers, and of course the organizers. You can learn more about the event at the page I linked to above. I highly recommend it - great venue and setup, and fantastic people. I connected and made friends with many people in both the .NET and programming community in general.
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=258&amp;g2_serialNumber=2" alt="X-Fit Sample Application"/&gt;
&lt;p&gt;For my talk on advanced applications in Silverlight using the Managed Extensibility Framework, I built a sample application called "the &lt;a href="http://apps.jeremylikness.com/samples/x-fit/" title="X-Fit Sample Application" target="_blank"&gt;X-Fit Sample Application&lt;/a&gt;." I often hear complaints that demos and blog posts focus on one screen and a button. I wanted to build something with more depth than that, and used that application for my presentation. 
&lt;p&gt;What does it demonstrate? 
&lt;ul&gt;&lt;li&gt;Region management&lt;li&gt;De-coupling of views and view models&lt;li&gt;Dynamic loading of XAP files on-demand&lt;li&gt;OOB (Out-of-Browser)&lt;li&gt;Recognizing out of browser and behaving differently&lt;li&gt;Loading a plugin from the file system&lt;li&gt;Messaging using MEF&lt;li&gt;"Tracing" using Debug&lt;li&gt;Debugging MEF parts (imports and exports)&lt;li&gt;...and plenty more&lt;/ul&gt;
&lt;p&gt;You can click here to view: &lt;a href="http://apps.jeremylikness.com/samples/x-fit/" title="X-Fit Sample Application"&gt;X-Fit Sample Application&lt;/a&gt;
&lt;p&gt;The source code and slide shows from my deck are both available at this link: 
&lt;p&gt;&lt;a href="http://jeremylikness.com/codestock2010/" target="_blank"&gt;Deck and source&lt;/a&gt;
&lt;p&gt;To use the application, jump into it and fill out the information. You'll find the first example of dynamic loading because once you save the information, the additional tabs will load with some charts and graphs. If you close the application, then re-launch it, it will automatically detect your user (using isolated storage) and not show the set up screen again. 
&lt;p&gt;You can right click and install locally. If you access the BMR tab (graphs showing basal metabolic rate) you'll notice a help link for more information. In the web version, this will simply pop open a new window to a Wikipedia page. In the out-of-browser version, it will introduce a new tab and show the information inline using the web browser control. 
&lt;p&gt;The little "plus" and "x" demonstrate different features. The "x" simply throws an error. If you are viewing the application, you'll get a generic message. If you are debugging, it will show the debug dump information. 
&lt;p&gt;There is a "SampleApplicationData" project included with the main source. It will build but is not referenced in the project. If you click the "plus" sign, you'll get an open file dialog. You can then browse to the XAP for the sample data, and click it. When you then refresh the application, it will be loaded with "John Doe" and some sample data. 
&lt;p&gt;A second code stock example will create a XAP that you can right-click and download here: &lt;a href="http://jeremylikness.com/codestock2010/CodeStockExample.xap" title="CodeStock plug-in"&gt;CodeStock Example (right-click and download)&lt;/a&gt;. Click the plus, browse to the XAP, and then select it to see the CodeStock logo.
&lt;p&gt;Obviously there is a lot more in the slide deck and in the source code. Understand I'm not trying to establish best practices - for example, the simple messenger may not be the right implementation if you have views that are short-lived (due to event references) and &lt;a href="http://compositewpf.codeplex.com/" target="_blank"&gt;PRISM&lt;/a&gt; provides very robust region management "out of the box" you can use. The idea here was to demonstrate what is possible in a sample application that goes a little deeper than a view and a button.
&lt;p&gt;Oh, and thanks to the Silverlight team for the  &lt;a href="http://timheuer.com/blog/archive/2010/05/03/new-silverlight-4-themes-available-for-download.aspx" target="_blank"&gt;Cosmopolitan theme&lt;/a&gt;.
&lt;p&gt;Thanks again, everyone, it was a great experience and I hope to come back in the future.
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-8283329341817396070?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://jeremylikness.com/codestock2010/' title='Advanced Silverlight Applications using the Managed Extensibility Framework'/><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/8283329341817396070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/06/advanced-silverlight-applications-using.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/8283329341817396070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/8283329341817396070'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/06/advanced-silverlight-applications-using.html' title='Advanced Silverlight Applications using the Managed Extensibility Framework'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-6770868319998203413</id><published>2010-06-16T08:43:00.002-04:00</published><updated>2010-06-16T08:52:46.510-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mvvm'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight test'/><category scheme='http://www.blogger.com/atom/ns#' term='prism'/><title type='text'>Silverlight UI Automation and Full VS 2010 Integration</title><content type='html'>&lt;p&gt;OK, so it's not exactly "out of the box" but the most recent &lt;a href="http://blogs.msdn.com/b/blaine/archive/2010/06/16/prism-4-0-plan-amp-drop-available-on-codeplex.aspx" target="_blank"&gt;PRISM 4.0 Drop (drop 2)&lt;/a&gt; seems to contain something Silverlight developers have been begging for ... for quite some time. 
&lt;p&gt;It's buried within the "QuickStart" folder under the "BasicMVVM" project. This project provides guidance for the &lt;a href="http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html" target="_blank"&gt;Model-View-ViewModel&lt;/a&gt; pattern and is worth a deep look. It may provide a basic framework for your future applications.
&lt;p&gt;In that same folder, you'll find &lt;code&gt;BasicMVVM.Tests.AcceptanceTest&lt;/code&gt;. Fire this project up and take a look at it. It contains some helper classes and launchers to host the Silverlight automation piece. If you're impatient like me, build and fire it off. That is where you start to have fun! 
&lt;p&gt;&lt;img src="http://gallery.jeremylikness.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=255&amp;g2_serialNumber=2" alt="Silverlight Test Integration" title="Silverlight Test Integration"/&gt;
&lt;p&gt;Yes, that is the test panel within Visual Studio 2010, not the Silverlight Unit Testing Framework in a browser window. Even more interesting is watching the form appear on the screen, then automatically get filled out by the engine as the acceptance tests are run. 
&lt;p&gt;So what we have here is full UI automation for tests as well as VSTS integration.
&lt;p&gt;This is obviously a huge jump for Silverlight ... I'm looking forward to digging in deeper to explore what's possible with this! 
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-6770868319998203413?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blogs.msdn.com/b/blaine/archive/2010/06/16/prism-4-0-plan-amp-drop-available-on-codeplex.aspx' title='Silverlight UI Automation and Full VS 2010 Integration'/><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/6770868319998203413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/06/silverlight-ui-automation-and-full-vs.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/6770868319998203413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/6770868319998203413'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/06/silverlight-ui-automation-and-full-vs.html' title='Silverlight UI Automation and Full VS 2010 Integration'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8944256652433533647.post-2431030444790390643</id><published>2010-05-25T19:08:00.005-04:00</published><updated>2010-05-25T20:03:50.268-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MEF'/><category scheme='http://www.blogger.com/atom/ns#' term='silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='out of browser'/><category scheme='http://www.blogger.com/atom/ns#' term='deploymentcatalog'/><category scheme='http://www.blogger.com/atom/ns#' term='isolated storage'/><title type='text'>Silverlight Out of Browser Dynamic Modules in Offline Mode</title><content type='html'>&lt;p&gt;Silverlight Out of Browser (OOB) applications are becoming more and more popular due to the convenience of being able to install and launch them locally. As Silverlight applications become larger and more composable, advanced techniques such as dynamically loading modules are also becoming more popular. 
&lt;p&gt;The "out of the box" Managed Extensibility Framework provision for dynamic modules is the &lt;code&gt;DeploymentCatalog&lt;/code&gt;. This will download a XAP file based on a URI and integrate it with the current solution. It also works in OOB mode and will attempt to retrieve the URI from the same location as the in-browser version (the only caveat is that you must specify the absolute, rather than relative, URI). 
&lt;p&gt;What happens if the user is running on their desktop, &lt;i&gt;and offline&lt;/i&gt;? This gets quite interesting. It turns out that most functions will simply use the browser cache, so if the items are cached then they will load with no problem. However, if the cache is cleared, you can run into problems. 
&lt;p&gt;To address this issue, I created the &lt;i&gt;OfflineCatalog&lt;/i&gt;. This MEF catalog behaves like the &lt;code&gt;DeploymentCatalog&lt;/code&gt; with a few exceptions. First, it will save any XAP file to isolated storage whenever it retrieves one, and second, if the application is OOB and offline, it will automatically load the XAPs from isolated storage instead of trying to fetch them from the web. 
&lt;p&gt;Instead of building my own catalog from scratch, I decided to cheat a little bit and use some of the existing catalogs "under the covers." To start with, we'll base the class on &lt;code&gt;ComposablePartCatalog&lt;/code&gt;. I'm setting up some helpers &amp;mdash; an aggregate catalog to aggregate the parts I discover, a list of assemblies to load from the XAP, and a static list of parts so that if I use multiple catalogs I won't ever try to load the same assembly more than once. It looks like this: 
&lt;pre class="brush: csharp;"&gt;
public class OfflineCatalog : ComposablePartCatalog
{
    private readonly AggregateCatalog _typeCatalogs = new AggregateCatalog();

    private readonly List&amp;lt;Assembly&gt; _assemblies = new List&amp;lt;Assembly&gt;();

    private static readonly List&amp;lt;string&gt; _parts = new List&amp;lt;string&gt;();

    public Uri Uri { get; private set; }

    public OfflineCatalog(string uri)
    {
        Uri = new Uri(uri, UriKind.Relative);
    }

    public OfflineCatalog(Uri uri)
    {
        Uri = uri;
    }

    public override IQueryable&amp;lt;ComposablePartDefinition&gt; Parts
    {
        get { return _typeCatalogs.Parts; }
    }
}
&lt;/pre&gt;
&lt;p&gt;This will asynchronously load, so I provide an event to "listen to" when the loading is complete: 
&lt;pre class="brush: csharp;"&gt;
...
public event EventHandler&amp;lt;AsyncCompletedEventArgs&gt; DownloadCompleted;
...
&lt;/pre&gt;
&lt;p&gt;Now I can wire up the download - it will simply try to download the XAP using a web client if the application is online, and read it from isolated storage if the application is offline: 
&lt;pre class="brush: csharp;"&gt;
public void DownloadAsync()
{
    if (NetworkInterface.GetIsNetworkAvailable())
    {
        Debug.WriteLine("Begin async download of XAP {0}", Uri);
        var webClient = new WebClient();
        webClient.OpenReadCompleted += WebClientOpenReadCompleted;
        webClient.OpenReadAsync(Uri);
    }
    else
    {
        _ReadFromIso();
    }
}
&lt;/pre&gt;
&lt;p&gt;For this example, I just take the full URI and replace some of the non-friendly characters with dots to make a filename - that is how I'll store/retrieve the catalog from isolated storage: 
&lt;pre class="brush: csharp;"&gt;
private string _AsFileName()
{
    return Uri.ToString().Replace(':', '.').Replace('/', '.');
}
&lt;/pre&gt;
&lt;p&gt;Now I can easily read in the file and send the stream off for processing: 
&lt;pre class="brush: csharp;"&gt;
private void _ReadFromIso()
{
    Debug.WriteLine("Attempting to retrieve XAP {0} from isolated storage.", Uri);

    using (var iso = IsolatedStorageFile.GetUserStoreForApplication())
    {
        if (iso.FileExists(_AsFileName()))
        {
            _ProcessXap(iso.OpenFile(_AsFileName(), FileMode.Open, FileAccess.Read));
        }
        else
        {
            if (DownloadCompleted != null)
            {
                DownloadCompleted(this, new AsyncCompletedEventArgs(
                                            new Exception(
                                                string.Format(
                                                    "The requested XAP was not found in isolated storage: {0}",
                                                    Uri)), false, null));
            }
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;Now it's simple to wire in the download event. Once downloaded, I simply write to isolated storage and then call the same method to parse it back out: 
&lt;pre class="brush: csharp;"&gt;
private void WebClientOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    Debug.WriteLine("Download of xap {0} completed.", Uri);

    if (e.Error != null)
    {
        // will try to read from ISO as a fallback 
        Debug.WriteLine("Catalog load failed: {0}", e.Error.Message);                
    }
    else
    {
        var isoName = _AsFileName();

        Debug.WriteLine("Attempting to store XAP {0} to local file {1}", Uri, isoName);

        using (var iso = IsolatedStorageFile.GetUserStoreForApplication())
        {
            using (var br = new BinaryReader(e.Result))
            {
                using (var bw = new BinaryWriter(iso.OpenFile(isoName, FileMode.Create, FileAccess.Write)))
                {
                    bw.Write(br.ReadBytes((int) e.Result.Length));
                }
            }
        }
    }

    _ReadFromIso();
}
&lt;/pre&gt;
&lt;p&gt;Notice if the load fails, I'll still try to read the isolated storage version as a fallback. Now we need to take a look at the "meat" of the method that reads from iso. The &lt;code&gt;ProcessXap&lt;/code&gt; method does several things. The &lt;code&gt;AppManifest.xaml&lt;/code&gt; provides us with a list of the parts (assemblies) contained. We parse that into a LINQ XML document and begin iterating it. We call a method that loads these into the assembly space and adds them to the list of assemblies. I add all of the assemblies first because I want to make sure any dependencies are already loaded before I start putting the parts into the MEF catalogs. Otherwise, MEF will choke if I try to add an assembly that references another assembly that hasn't been parsed yet. You can see how I take advantage of the existing MEF catalogs: for each assembly, I simply call the &lt;code&gt;GetTypes&lt;/code&gt; method, pass those into a &lt;code&gt;TypeCatalog&lt;/code&gt;, and add it to the aggregate catalog. When MEF asks us for the parts, I simply tell the aggregate catalog to pass along its parts. Take a look at this main loop: 
&lt;pre class="brush: csharp;"&gt;
private void _ProcessXap(Stream stream)
{
    var manifestStr = new
        StreamReader(
        Application.GetResourceStream(new StreamResourceInfo(stream, null),
                                        new Uri("AppManifest.xaml", UriKind.Relative))
            .Stream).ReadToEnd();

    var deploymentRoot = XDocument.Parse(manifestStr).Root;

    if (deploymentRoot == null)
    {
        Debug.WriteLine("Unable to find manifest for XAP {0}", Uri);
        if (DownloadCompleted != null)
        {
            DownloadCompleted(this,
                                new AsyncCompletedEventArgs(new Exception("Could not find manifest root in XAP"),
                                                            false, null));
        }
        return;
    }

    var parts = (from p in deploymentRoot.Elements().Elements() select p).ToList();

    foreach (var src in
        from part in parts
        select part.Attribute("Source")
        into srcAttr where srcAttr != null select srcAttr.Value)
    {
        _ProcessPart(src, stream);
    }

    foreach(var assembly in _assemblies)
    {
        try
        {
            _typeCatalogs.Catalogs.Add(new TypeCatalog(assembly.GetTypes()));
        }
        catch (ReflectionTypeLoadException ex)
        {
            Debug.WriteLine("Exception encountered loading types: {0}", ex.Message);

            if (Debugger.IsAttached)
            {
                foreach (var item in ex.LoaderExceptions)
                {
                    Debug.WriteLine("With exception: {0}", item.Message);
                }
            }

            throw;
        }
    }
    
    Debug.WriteLine("Xap file {0} successfully loaded and processed.", Uri);

    if (DownloadCompleted != null)
    {
        DownloadCompleted(this, new AsyncCompletedEventArgs(null, false, null));
    }

}
&lt;/pre&gt;
&lt;p&gt;So how do we process the parts? The &lt;code&gt;AssemblyPart&lt;/code&gt; provided by the framework takes care of it for us, as you can see here: 
&lt;pre class="brush: csharp;"&gt;
private void _ProcessPart(string src, Stream stream)
{
    Debug.WriteLine("Offline catalog is parsing assembly part {0}", src);

    var assemblyPart = new AssemblyPart();

    var srcInfo = Application.GetResourceStream(new StreamResourceInfo(stream, "application/binary"),
                                                new Uri(src, UriKind.Relative));

    lock (((ICollection)_parts).SyncRoot)
    {
        if (_parts.Contains(src))
        {
            return;
        }

        _parts.Add(src);

        if (src.EndsWith(".dll"))
        {
            var assembly = assemblyPart.Load(srcInfo.Stream);
            _assemblies.Add(assembly);                    
        }
        else
        {
            assemblyPart.Load(srcInfo.Stream);
        }
    }
}      
&lt;/pre&gt;
&lt;p&gt;Notice I am locking on the main list to make sure I don't load a duplicate. 
&lt;p&gt;That's it - now we can simply pass one or many of these catalogs to the composition host and we're good to go (basically, take a look at any examples that use the deployment catalog and use this in its place). 
&lt;p&gt;Now once the user has the application, they can run it offline even though the modules are dynamic. Of course, you'll have to download all modules first - you can put a check to see if it is running on the desktop and force a download to make it happen. It will also automatically check for new XAP files when going back online, so you can release updates to modules independent of the fully composed application.
&lt;p&gt;I don't have a project example for this but hope I've provided enough source for you to piece together the catalog yourself and take advantage of it in your Silverlight OOB applications.
&lt;p&gt;&lt;a href="http://jeremylikness.com/" title="Jeremy Likness"&gt;&lt;img border="0" src="http://jeremylikness.com/signature.gif" alt="Jeremy Likness" title="Jeremy Likness"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8944256652433533647-2431030444790390643?l=csharperimage.jeremylikness.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharperimage.jeremylikness.com/feeds/2431030444790390643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://csharperimage.jeremylikness.com/2010/05/silverlight-out-of-browser-dynamic.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/2431030444790390643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8944256652433533647/posts/default/2431030444790390643'/><link rel='alternate' type='text/html' href='http://csharperimage.jeremylikness.com/2010/05/silverlight-out-of-browser-dynamic.html' title='Silverlight Out of Browser Dynamic Modules in Offline Mode'/><author><name>Jeremy Likness</name><uri>http://www.blogger.com/profile/18407945801671553594</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='05667915713066003387'/></author><thr:total>3</thr:total></entry></feed>