Creating ViewModel to View mappings

One of my favorite approaches to creating View/ViewModel pairs in WPF it to use data templates. Say you have a ViewModel called MyViewModel and it should be displayed in the UI as the View MyView.

We can create a fairly straightforward DataTemplate defined as:

<DataTemplate DataType="{x:Type local:MyViewModel}">
  <local:MyView />
</DataTemplate>

Whenever we add the ViewModel instance into a Window or a ContentControl, it will render using the DataTemplate, which just happens to be the View.

If we ever run into a dynamic scenario in which we are unable to easily add static XAML as a resource dictionary into an existing resource dictionary, as we might in a Prism module scenario, we can use the following method instead. Just declare it in our MainWindow or Application and expose it through an interface inside that can be accessed through a service container.

public void RegisterViewModelToViewMapping()
{
    DataTemplate template = new DataTemplate(typeof(TViewModel));
    template.VisualTree = new FrameworkElementFactory(typeof(TView));

    DataTemplateKey key = new DataTemplateKey(typeof(TViewModel));
    Resources.Add(key, template);
}

WPFying DataRow

Our team encountered a strange issue recently. We have a strongly typed DataSet. We observed inconsistent behavior when binding our UI to DataRow objects or the DataRowView for those rows. In particular, WPF did not appear to refresh all the bindings when the DataRow’s column values changed. We also observed that property change notification on the DataRowView class did not work as expected.

We came up with a quick solution: WPFify the DataRow object. By this, we mean, have our DataRow class implement the INotifyPropertyChanged interface. Since the generated strongly typed DataRow is declared using partials, we are able to extend the class in another file. The fix is to simply handle the Table.ColumnChanged event and raise the corresponding INotifyPropertyChanged.PropertyChanged event.

        partial class MyDataRow : DataRow
        {
            ........... // auto generated contents
        }

        partial class MyDataRow : INotifyPropertyChanged
        {
            public void Wpfify()
            {
                Table.ColumnChanged += new DataColumnChangeEventHandler(HandleColumnChanged);
            }

            private void HandleColumnChanged(object sender, DataColumnChangeEventArgs e)
            {
                if (e.Row == this)
                {
                    OnPropertyChanged(e.Column.ColumnName);
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(string propertyName)
            {
                var ev = PropertyChanged;
                if (ev != null)
                {
                    ev(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

For our purposes, this has behaved well and has gotten rid of our problems with DataRow notifications.

WPF Dispatcher Frames

A few months ago, I read into some advanced WPF threading topics. One that had been particularly confusing to me is the idea of a DispatcherFrame. I hope that this article can shed some light on what it is, how they can be used and why we should care.

Message Loops

Win32 applications revolve around the concept of a message loop. Any interaction that occurs with it, be it a a mouse over, a keyboard event or a paint message, is queued up and the application needs to process it. The UI thread is responsible for retrieving the operation from a queue and correctly executing it. HIstorically speaking, the concept of an event loop has been around for a long time. For more background on the Win32 message loop, see here.

A sample message loop in Win32 looks like this:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

The message loop is a central concept in the Win32 API. Frameworks like Windows Forms and WPF attempt to abstract these concepts as much as possible: WinForms is just a managed wrapper around this. Although WPF is a step into the managed world, it still revolves around the concept of a message loop.

The Dispatcher

Any WPF application has a Dispatcher object associated with it. A Dispatcher object is a wrapper around the application’s message loop. In fact, with a little bit of exploration, you can find this little gem:

while (/* intentionally left out for now*/)
{
   if (!this.GetMessage(ref msg, IntPtr.Zero, 0, 0))
   {
       break;
   }
   this.TranslateAndDispatchMessage(ref msg);
}

The queue of DispatcherOperations is processed from this queue. A method like Dispatcher.BeginInvoke simply inserts a DispatcherOperaton into the loop.

So what are these frames?

A DispatcherFrame is a message loop inside the Dispatcher. The Dispatcher essentially has a stack of DispatcherFrames that it uses the execute the queue of DispatcherOperations. The topmost frame is the frame responsible for the current queue processing. The only way for a frame to terminate is if its Continue property is set to false.

The main functionality a DispatcherFrame provides is the ability to block a UI operation, while the system can continue to process UI events. The blocking call is the call to Dispatcher.PushFrame(DispatcherFrame).

Let’s reveal another part of the gem mentioned above:

public static void PushFrame(DispatcherFrame frame)
{
    ...

    while (frame.Continue)
    {
        if (!this.GetMessage(ref msg, IntPtr.Zero, 0, 0))
        {
            break;
        }
        this.TranslateAndDispatchMessage(ref msg);
    }

    ...
}

Pushing a frame starts a new message loop inside the current message loop. So we aren’t looking really at some internal Stack<DispatcherFrame>, but rather at a stack of PushFrame method calls. To reiterate, PushFrame blocks the current call but keeps on processing other GUI events.

The implementation of Dispatcher.Run is pretty clear:

PushFrame(new DispatcherFrame());

So what?

Why do we need nested loops to execute our UI? There are few examples out there. A while go, Kent Boogaart wrote an interesting post in which he illustrates one such case.

I’m not entirely sold on whether this is the only approach to this problem. One certainly has the ability to use Window.ShowDialog() though the blocking of the Main Window might be an issue. If you are executing a method on the UI thread and this method requires message pumping, then PushFrame is what you are looking for.

There are other things that can be done with PushFrame, like something similar to Application.DoEvents as described in the MSDN docs.

I hope that this article has provided some clarity on this rarely used part of the WPF Threading model.

Controlling UI using power shell (part 1)

Ever since PowerShell was released, I’ve been very interested in the technology. Coming from a linux background, I love the command line. And, let’s face it, cmd is shameful.

I have been imagining a UI environment in which at any point, anyone can enter into a command line and have access to all of the objects in the application. If you are following the MVVM design pattern, you could get an instance of the view model and change properties on it or invoke commands.

PowerShellMVVM

Using the PowerShell 2.0 SDK, this is possible. There are a number of ways of implementing this functionality. In this and a few additional posts, I will cover a large amount of the PowerShell 2.0 SDK, and a few implementations of the desired functionality.

What is PowerShell

PowerShell is Microsoft’s new command line shell and scripting environment. It’s better than cmd in many ways and inherits a lot of ideas from unix shells. The thing that attracted me most to the shell is that it is based on the .Net framework. Scripts and commands in PowerShell don’t return text, but, they return .Net objects.

PowerShell SDK: basics

PowerShell 2.0 includes the PowerShell SDK. There are a number of classes in the System.Automation.Management Assembly that allow you to build various custom features. For example, you can create custom PowerShell commands known as Cmdlets and you can also implement PowerShell Providers. PowerShell then allows you to create a custom PowerShell SnapIn. Activating a PowerShell SnapIn in a PowerShell instance will expose all Cmdlets and Providers registered in the snap to the PowerShell instance.

There is an additional set of PowerShell classes under the System.Management.Automation.Runspaces that allow us to programmatically create an in-memory instance of PowerShell. The developer would create a Runspace, which is a factory for execution Pipelines. Each pipeline is able to execute scripts or commands.

An interesting point about Runspaces, is that they support programmatic addition of SpanIns. You can register your Cmdlets with your Runspace and use scripts that invoke your Cmdlets. Runspaces also support registering variables.

A first attempt

My first attempt at a integrated UI and PowerShell environment was based on the knowledge of the SDK above. This approach is not horribly wrong, but does not work in numerous cases. I will explain further in my next post. The final result was a WPF user control called PowerShell.Wpf. The image in the beginning of this post illustrates a session in this control. I register my ViewModel as the variable “vm” in the Runspace. It is then exposed in the instance and I can use it and modify it. In the sample above, I have changed the Data property of the view model. This change is reflected in the UI itself.

The rest of this article describes the implementation of the PowerShell control.

PowerShell.Wpf implementation

The user control is implemented as a MVVM component. The View is simply a readonly TextBox in which we show the commands invoked and their output. Below, is a single row TextBox that allows us to insert commands. The control supports 3 commands: Execute, LoadPrevious and LoadNext. LoadPrevious and LoadNext allow us to use the up and down arrow keys to navigate over the command history. The Execute command executes the PowerShell command.

Each command executed in the UI is represented by the PowerShellCommand class. This class stores the original command string, the time when it was executed and the result. For the implementation of command history, a command can also be based on a previous command.

The CommandHistoryManager class is able to manage the history of all executed commands and its string representation, which is the string that is displayed in the output TextBox.

PowerShellSessionManager is the meat of the implementation. The constructor opens up the Runspace in which every command will execute and there is a method that allows clients to register session variables with the Runspace.

public PowerShellSessionManager()
{
    Runspace = RunspaceFactory.CreateRunspace();
    Runspace.Open();
}

...

public void RegisterSessionData(string name, object value)
{
    Runspace.SessionStateProxy.SetVariable(name, value);
}

When a script is ready to be executed, we the ExecuteCommand(PowerShellCommand) method is called.

public string ExecuteCommand(PowerShellCommand command)
{
    var pipeline = Runspace.CreatePipeline();

    System.Collections.ObjectModel.Collection<PSParseError> parseErrors =
        new System.Collections.ObjectModel.Collection<PSParseError>();

    var parsedTokens = PSParser.Tokenize(command.Command, out parseErrors);

    if (parseErrors.Count > 0)
    {
        var report = BuildErrorReport(parseErrors);
        Debug.WriteLine(report);
        return report;
    }

    Command c = new Command(command.Command, true);
    pipeline.Commands.Add(c);

    IEnumerable<PSObject> result = null;
    try
    {
        result = pipeline.Invoke();
    }
    catch (RuntimeException e)
    {
        string message = string.Format("Found error while trying to invoke command.\n{0}", e.ToString());
        Debug.WriteLine(message);
        return message;
    }

    var resultStr = BuildResultOutput(result);
    return resultStr;
}

private string BuildResultOutput(IEnumerable<PSObject> result)
{
    var builder = new StringBuilder();

    foreach (PSObject resultObj in result)
    {
        if (resultObj == null)
        {
            builder.AppendLine("[null]");
        }
        else
        {
            var temp = resultObj.ToString();
            builder.AppendLine(temp);
        }
    }

    var resultStr = builder.ToString();
    return resultStr;
}

A few useful points:

  • The PSParser.Tokenize method can be used to verify whether there are any syntax errors in your script.
  • There are a few ways to create Command objects to execute commands. The object can be constructed with just the command name and each parameter/argument must be passed in using the object model. This is a lot of work and involves parsing the string. Fortunately, the class supports any input string as long as the second boolean argument is set to true to indicate that the string is a script.

The full code for the PowerShell.Wpf control and the sample can be found here.

A WPF Splash Screen

When I was first looking into displaying a splash screen in a WPF app, I found a large number of examples using some managed code. I then found some samples using .Net 3.5 Sp1’s WPF Splash Screen implementation. None of these really suited my requirements. We weren’t looking for only displaying an image. We were looking to display some sort of status for the users and, quite frankly, for ourselves. We wanted the flexibility to display any WPF content and, more importantly, we had other initialization logic that needed to execute on the UI thread!

The motivation

The UI was a composite UI and we were initializing numerous plugins. At first, the shell displayed the Main Window and then we called the Initialize() logic for each plugin. The problem was that plugins were able to do anything in the initialize code, including calling services, initializing controls, etc. The resulting behavior was a window that was unresponsive and looked frozen until all plugins were initialized. Even if they did not do things on the UI thread, initializing over 8 plugins was not seamless (load from disk, JIT some code, etc). We decided that we did not want to suffer the frozen main window on startup curse. Instead, let’s initialize everything first and only show the window once everything is good to go.

Only now we had nothing on the screen for some time. The solution: a splash screen that can display messages and allow execution to occur on the UI thread. Since there was one large initialization method executing on the main UI thread, we did not want to bring in a complex splash screen that needs message pumping on the same thread.

Solution

The solution is fairly simple. A WPF app has one main UI thread. However, we are able to create any number of separate, independent UI threads. The solution is to create a new STA thread in which we run a separate Dispatcher that hosts the splash screen window. In retrospect, this would have been a perfect place to use the power of DispatcherFrames, but I’ll address this in a future post.

Our client code should be something like this:

using (ISplashScreen splashScreen = SplashScreenManager.CreateSplashScreen())
{
    // do lots of work on UI thread
}

with ISplashScreen defined as:

/// 
/// Contract through which client application can talk to the splash screen
/// 
public interface ISplashScreen : IDisposable
{
    /// 
    /// The text message being displayed in the splash screen
    /// 
    string Message { get; set; }

    /// 
    /// The content object displayed in the splash screen window
    /// 
    /// 
    /// This method sets the Content element in the Splash Screen. Cannot
    /// accept an object because any UI element needs to be initialized in
    /// the splash screen's UI thread.
   void SetContentObject(Type objectType);
}

The idea behind SetContentType is that we are unable to set the Content of the screen directly, since the UI element would need to be created in the same thread and the splash screen. For simplicity, we assume the content object is static (maybe an image) and simply have the splash screen manager initialize the type.

The magic behind CreateSplashScreen is pretty straightforward.

public class SplashScreenManager
{
    private static object mutex = new object();

    public static ISplashScreen CreateSplashScreen()
    {
        lock (mutex)
        {
            SplashScreenWindowViewModel vm = new SplashScreenWindowViewModel();

            AutoResetEvent ev = new AutoResetEvent(false);

            Thread uiThread = new Thread(() =>
            {
                vm.Dispatcher = Dispatcher.CurrentDispatcher;
                ev.Set();

                Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate()
                {
                    SplashScreenWindow splashScreenWindow = new SplashScreenWindow();
                    splashScreenWindow.DataContext = vm;
                    splashScreenWindow.Show();
                });

                Dispatcher.Run();
            });

            uiThread.SetApartmentState(ApartmentState.STA);
            uiThread.IsBackground = true;
            uiThread.Start();
            ev.WaitOne();

            return vm;
        }
    }
}

The result is a splash screen with its own UI thread. We use the MVVM pattern in the background. The SplashScreenViewModel object is the Window’s ViewModel and implements the ISplashScreen interface for clients.

The CreateSplashScreen method creates a new Background STA thread. This thread queues up the SplashScreenWindow initialization code and runs the Dispatcher on the thread. As soon as the Dispatcher is ready, the splash screen will show up. The ViewModel’s Dispatcher object must be set before we can call SetContentObject(Type) on it (this method needs to create the Type using the Dispatcher object), so we synchronize between the calling thread and the splash screen initialization thread so that Dispatcher will always be set when the ISplashScreen instance is returned.

The library currently only supports a rectangular window with static content. It should be fairly easily to modify this library to support non-rectangular windows and dynamic content, as long as all UI operations are somehow executed on the splash screen’s Dispatcher.

Notes

  • Performance is not a real consideration for this approach to the splash screen. The idea here is not to shave milliseconds off, but rather provide some feedback to the user. We prefer to display something live to the user as soon as possible rather than worry about milliseconds during start up. On a fast machine, the extra time spent to spin off a new thread and display the splash screen is not significant.
  • At one point, we had our UI initialization logic spread across two AppDomains. In that case, the splash screen manager class inherited from MarshalByRef and we were able to share one instance across multiple AppDomains.

You can download the library here.

Referencing generic types in XAML

This post is an elaboration of my answer on StackOverflow to a question about referencing a generic type in XAML. The first responder had a good idea on how to approach the problem. It did not solve the question for the author, so I went ahead and elaborated on his approach and created a generic solution.

The problem

If we want to create a generic type in C#, we have to write the following code:

Type t = typeof(System.Collections.Generic.List<>);
Type listOfInts = t.MakeGenericType(typeof(int));

However, this approach is not possible using the x:Type Markup Extension since it can only get a type based on string.

Even though the type List<int> can be represented using the string:
System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], the x:Type markup extension is unable to parse this since it includes invalid XML.

A custom markup extension

The solution is a custom MarkupExtension.We will call it GenericType. Looking back at the first piece of code, we need two pieces of information to build the correct concrete Type object: the base generic type and the parameter types. One of the main observations here is that we can retrieve the base generic type in XAML using the ` syntax.

For example, System.Collections.Generic.List<> can be represented as the string System.Collections.Generic.List`1. The character ` tells .Net that it is a generic type and the number is the amount of Type parameters that the type takes. Dictionary<K,V> could be referred to as System.Collections.Generic.Dictionary`2. XAML supports this syntax. Assuming the xml namespace coll maps to System.Collections.Generic, we can retrieve the generic types using the x:Type Markup Extension as follows:

...
<obj Type="{x:Type TypeName=coll:List`1}" />
...

The resulting class is:

public class GenericType : MarkupExtension
{
    public Type BaseType { get; set; }
    public Type[] InnerTypes { get; set; }

    public GenericType() { }
    public GenericType(Type baseType, params Type[] innerTypes)
    {
        BaseType = baseType;
        InnerTypes = innerTypes;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        Type result = BaseType.MakeGenericType(InnerTypes);
        return result;
    }
}

That’s all! We can now support any kind of generic type in our XAML.

    <Window.Resources>
        <x:Array Type="{x:Type sys:Type}"
                     x:Key="TypeParams">
            <x:Type TypeName="sys:Int32" />
        </x:Array>

        <local:GenericType BaseType="{x:Type TypeName=coll:List`1}"
                               InnerTypes="{StaticResource TypeParams}"
                               x:Key="ListOfInts" />

        <x:Array Type="{x:Type sys:Type}"
                     x:Key="DictionaryParams">
            <x:Type TypeName="sys:Int32" />
            <local:GenericType BaseType="{x:Type TypeName=coll:List`1}"
                                   InnerTypes="{StaticResource TypeParams}" />
        </x:Array>

        <local:GenericType BaseType="{x:Type TypeName=coll:Dictionary`2}"
                               InnerTypes="{StaticResource DictionaryParams}"
                               x:Key="DictionaryOfIntsToListOfInts" />
    </Window.Resources>

If we call the following in our code behind:

Type customGenericType = (Type)Resources["DictionaryOfIntsToListOfInts"];

the result is:

System.Collections.Generic.Dictionary`2[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

or quite simply: Dictionary<int, List<int>>.

The resulting XAML can be somewhat verbose if you get into deeply nested generic types. Another solution to this problem is to write a MarkupExtension that will accept a string and just simply parse the string. That approach can lead to some issues with regards to type resolution and parsing. Instead of dealing with that, I decided to use this approach.

Custom Resolver

In my previous post, I explained a problem that we have encountered with .Net, WPF and custom Assembly redirection.

In this post, I will explain how to build a custom resolver class that can attach to an AppDomain and redirect the assembly requests to whatever assembly you would like it to. Recall that if the .Net runtime is unable to locate a particular assembly, it will raise the AppDomain’s AssemblyResolve event. If the handler for this event returns an Assembly, .Net will bind to it. We will use this event to implement the resolver.

Requirements

The resolver should be able to:

  1. Load an Assembly from anywhere on the local desktop
  2. Redirect a request from an Assembly to any other Assembly

Representing the problem

The main class we are going to work with is Resolver. This class will attach to an AppDomain’s AssemblyResolve event. We will need some configuration objects to configure the Resolver. For simplicity, the resolver object will be immutable.

We require the concept of a path from which .Net can load the Assemblies. In .Net, this is known as a probing path. However, for security reasons (more on this later), .Net is unable to bind to Assemblies anywhere on the desktop. Our resolver will allow this feature and the paths will be represented by the ProbingPath class.

We also need the concept of a RedirectionItem. In our problem, we will have two kinds of redirection items:

  • VersionRedirectionItem, which redirects from one version to another version of a single Assembly Name.
  • AssemblyRedirectionItem, which redirection from one Assembly version to any other Assembly.

The sample below utilizes inheritance to represent the redirection items, though other approaches may be more appropriate.

These classes will fulfill our requirements.

Executing the redirection and probing

A Resolver is just a collection of ProbingPaths and RedirectionItems. The AssemblyResolve handler will check if the AssemblyName being looked for needs to be redirected using the redirection item collection. There is a possibility for multiple redirections and circular dependencies so our code should be able to handle this in a recursive manner (… I love recursive code).

public AssemblyName GetAssemblyNameToLoad(AssemblyName currentName)
{
    List<RedirectionAction> visitedActions = new List<RedirectionAction>();
    AssemblyName name = GetAssemblyNameToLoad(currentName, visitedActions);
    return name;
}

private AssemblyName GetAssemblyNameToLoad(AssemblyName currentName,
        List<RedirectionAction> visitedActions)
{
    var actions = this[currentName.Name];
    AssemblyName nextAssemblyName = null;

    foreach (var action in actions)
    {
        if (action.ShouldRedirectAssembly(currentName))
        {
            if (visitedActions.Contains(action))
            {
                throw new Exception(string.Format("Circular dependency path detected. {0}", action.ToString()));
            }

            visitedActions.Add(action);
            nextAssemblyName = action.GetRedirectedAssembly(currentName);

            break;
        }
    }

    if(nextAssemblyName == null) return currentName;

    nextAssemblyName = GetAssemblyNameToLoad(nextAssemblyName, visitedActions);
    return nextAssemblyName;
}

The logic for the Resolve method is simply:

public Assembly Resolve(string assemblyName)
{
    Assembly asm = null;
    var name = new AssemblyName(assemblyName);
    AssemblyName assemblyToGet = null;

    if (name.Version != null)
    {
        assemblyToGet = GetAssemblyNameToLoad(name);
    }

    foreach (var input in probingPaths)
    {
        if (!input.ContainsAssembly(assemblyToGet.Name))
            continue;

        if (assemblyToGet.Version == null) { asm = input.Load(assemblyToGet.Name); }
        else
        {
            asm = input.Load(assemblyToGet.Name, assemblyToGet.Version);
            if (asm != null)
                break;
        }
    }

    return asm;
}

Implications

With regards to performance, each assembly load takes about 10ms. The difference between this and the .Net binding engine is insignificant. The probing path objects cache the contents of the path so there is 0 I/O operations when it comes to finding the proper assembly to load.

One thing to be careful of. All of this logic executes after the four steps specified by the How the Runtime Loads Assemblies document. This means that if .Net finds the originally requested assembly in the GAC or through some sort of private probing path or assembly binding redirection, this logic will never kick in. This code does not have logic to deal with the GAC. Additionally, if the assembly is found in the working directory, the AssemblyResolve event will never kick in. This means that if your application is built against LibA.dll v 1.0.0.0 and you’d like to redirect the app to LibA.dll v 2.0.0.0, the 1.0.0.0 Assembly should not exist int he working directory.

This code is not meant to be secure but rather to illustrate the mechanisms through which .Net binds assemblies. In fact, as long as the .Net can’t bind to an assembly using its standard binding mechanisms, the resolver could be used to execute any arbitrary .Net code.

The Sample

You can find a sample implementation ResolverSample here. This code is a quick and dirty demo of the redirection concepts. The RedirectionItem and subclasses and the Version Range classes should most likely implement IComparable. In addition, the ResolverConfiguration class should make sure no duplicate probing paths or redirection items are inserted.

The idea in the sample is the following. I have two libraries that define the type: Lib.Class1. The two assemblies are: Lib1 and Lib2. There are two versions of each library: 1.0.0.0 and 2.0.0.0. All 4 builds print out “AssemblyName Version”, so: Lib1 1.0.0.0 will print out “Lib1 1.0.0.0″, Lib2 2.0.0.0 will print out “Lib2 2.0.0.0″, etc.

By default, the sample application is built against Lib1 version 1.0.0.0.

static void Main(string[] args)
{
    List<string> probingPaths = new List<string>();
    probingPaths.Add(@"Library\lib1\1.0.0.0");
    probingPaths.Add(@"Library\lib1\2.0.0.0");
    probingPaths.Add(@"Library\lib2\1.0.0.0");
    probingPaths.Add(@"Library\lib2\2.0.0.0");

    VersionRedirectionItem lib1from1to2 =
       new VersionRedirectionItem("Lib1", VersionRange.CreateVersionRange("1.0.0.0"), new Version("2.0.0.0"));

    AssemblyRedirectionItem lib1tolib2_1 =
       new AssemblyRedirectionItem("Lib1",VersionRange.CreateVersionRange("1.0.0.0"),
                                               "Lib2", new Version("1.0.0.0"));
    AssemblyRedirectionItem lib1tolib2_2 =
       new AssemblyRedirectionItem("Lib1", VersionRange.CreateVersionRange("1.0.0.0"),
                                               "Lib2", new Version("2.0.0.0"));

    List<RedirectionItem> redirection = new List<RedirectionItem>();

    // By default, the output of the program will be: Lib1 1.0.0.0

    // If you uncomment this, the output will be: Lib1 2.0.0.0
    // redirection.Add(lib1from1to2);

    // If you uncomment this, the output will be: Lib2 1.0.0.0
    //redirection.Add(lib1tolib2_1);

    // If you uncomment this, the output will be: Lib2 2.0.0.0
    //redirection.Add(lib1tolib2_2);

    ResolverConfiguration config = new ResolverConfiguration(probingPaths, redirection);

    using (Resolver.Resolver resolver = Resolver.ResolverFactory.CreateResolver(config))
    {
        Runner runner = new Runner();
        runner.Run();
    }
}

The directory in which the sample.exe lives has a Library folder with both Lib1 and Lib2 versions in the sub folder structures passed into the probing paths configuration entry. Depending on which redirection item we pass into the ResolverConfiguration, we will see different outputs from the Run() method.

In this sample, the redirection is inserted programmatically but there is no reason we can’t deserialize the configuration from any external config file.

I hope this post helps clarify how the .Net framework binds Assemblies at runtime.

Redirection to an Assembly with a different name (and why it might not work in WPF)

The .Net framework allows a great deal of flexibility when it comes to loading assemblies. In our composite UI framework, we build strongly named assemblies in which versions matter. Strong naming a .Net assembly does a number of things, but, for the purposes of this post, it allows us to build applications against specific versions of a dependent assembly.

For example: our core library CompositeUICore.dll has gone through numerous iterations and on every release, we increment the version. We’ve gone through 1.0.0.0, 1.1.0.0, 1.2.0.0, 1.3.0.0, 1.3.1.0 and 1.4.0.0. Any application that consumes the CompositeUICore assembly is built against a specific version of the assembly. If, during runtime, the specific version is not found, a runtime exception is raised because .Net cannot load the assembly.

Assembly Binding Redirection

.Net supports something called Assembly Binding Redirection. This feature allows us to tell the .Net runtime that any Assembly that binds to some version of Assembly A, should redirect to a different version. For example, we can build an application against CompositeUICore.dll 1.0.0.0 but using an entry in the app.config file, we can tell .Net Fusion binding engine to bind to CompositeUICore.dll 1.3.1.0. .Net will do the binding, but if there’s an API break, a runtime exception will occur (In the same way if we replaced a non-strong named assembly). This technique is ok for simple, static redirection but bad for dynamic scenarios in which we may want to redirect based on some parameters.

If you have a composite UI and your redirection options will depend on which plugins you are loading and you want to dynamically set up the redirection, a static configuration in the app.config file is not ideal.

A more complex problem

We had an interesting scenario in our composite UI the past month. We work with the Infragistics WPF controls. We’ve been using version 9.1 of the controls but they recently came out with version 9.2. Since the plugin ecosystem for our shell is ever-growing, we try to avoid having everyone rebuild their UIs against the new version. However, if we can dynamically redirect all plugins to the new version, we’d just have to ask them to test their UIs. Less work for our client developers is always better.

Our first roadblock was that Infragistics has a strange way of versioning their WPF libraries. Every major release of their product has the version embedded in the assembly name. For example, 9.1 libraries were named Infragistics3.Wpf.9.1.* and 9.2 libraries are Infragistics3.Wpf.9.2.*. However, both libraries have the same namespaces and the API is, for the most part, backwards compatible.

Enter AssemblyResolve

The problem with a changing assembly name is that we cannot use Assembly Binding Redirection because the assembly names are different. So how can we do the redirection seamlessly? To answer this question, we need to take a step back and examine how the .Net fusion engine binds to assemblies. .Net locates an assembly through 4 steps:

  1. Determines the correct assembly version
  2. Checks whether the assembly name has been bound to before and, if so, uses the previously loaded assembly.
  3. Checks the global assembly cache
  4. Probes for the assembly

Given these steps, we are not really able to redirect to an Assembly with a different name. So where do we go from here? One thing that the documentation fails to mention, is that if the assembly is not found after all of these steps, the current AppDomain’s AssemblyResolve event is raised. An event handler receives the full Assembly name that .Net is trying to load and should return an instance of an Assembly. If the return value is null, .Net throws an exception. On the other hand, if we return a valid assembly, .Net accepts it.

The mechanics of the event are simple. .Net doesn’t know where the assembly is, so here’s some IoC. .Net says, you find it if you want it that badly! Our plan of attack is simple then. If we are asked for an assembly with name Infragistics3.Wpf.9.1.dll, we call Assembly.Load(”Infragistics3.Wpf.9.2″) and return the result.

The problem with WPF

However, this will not work in WPF. Let’s say you have a UserControl with the following XAML:

<UserControl xmlns:igDP="http://infragistics.com/DataPresenter" ... >
    <igDP:XamDataGrid ... />
</UserControl>

When this XAML is built, it will bind to the referenced Infragistics dll. In our sample, this will be version 9.1. Interestingly enough, WPF has a set of assembly loading helpers that do not allow the AssemblyResolve event to redirect to differently named assemblies more than once.

The WPF system will try to load the Assembly. If it has not been loaded before, it calls Assembly.Load(…). Our AssemblyResolve handler kicks in and resolves the assembly just fine. WPF caches the AssemblyName to load and the resulting Assembly instance. So, on the first time your UserControl requests the assembly, this works.

If you try to load another UserControl that also references Infragistics 9.1, you will be in trouble. The WPF system will notice that it has cached the Assembly. Instead of just returning it, it will verify that the AssemblyName that is requested and the AssemblyName that we have cached match. The match is actually a comparison of the Assembly’s short name. In the case above, it will notice that Infragistics3.Wpf.9.1 and Infragistics3.Wpf.9.2 are not equal strings, so it will throw an exception.

So…

Our conclusion is that WPF adds an extra check to the Assembly name that it is loading matches the Assembly name requested. This logic will break dynamic assembly redirection to a differently named Assembly when using the Assembly Resolve event. At this moment, I am not aware of a work around to this issue.

In a future post, I will show you how to use the AssemblyResolve event to implement custom redirection and probing.

First post

Blog is up! Excellent!

I’ll be playing around with the blog’s theme in the coming days. I am very much into a minimalist design style (my favorite ice cream flavor is vanilla) so don’t expect anything fancy!