Archive

Archive for the ‘MVVM’ Category

Creating a custom Knockout binding for the jQuery Mobile ListView

September 22, 2012 3 comments

Introduction

A shift towards more client side web development is happening in the IT industry. This allows developers to build quicker responding and more user friendly GUIs for their end users. This shift is made possible with the arrival of HTML5 and more powerful JavaScript frameworks. Features like camera access, local storage, drag & drop … previously only available in native applications are now also possible in web applications.

In the past I have already written about jQuery Mobile. It is an excellent JavaScript framework to develop mobile web applications or hybrid applications. Another useful framework for the development of modern web applications is Knockout. This framework makes the MVVM design pattern possible in web applications. MVVM stands for Model-View-ViewModel. It is a software pattern of Microsoft commonly used in WPF and Silverlight applications.

In this article I will explain how to build a custom Knockout binding for the jQuery Mobile ListView.

Context

Why do we need a custom binding for the jQuery Mobile ListView? With what is provided out of the box, it is already possible to bind to a ListView. Unfortunately, we are then rather limited in functionality. Imagine the following example: I have a JavaScript array of food. The food can be divided in a number of categories (fruit, vegetables and snacks). I want to show the food in a jQuery Mobile ListView and show a divider per category.

foodapp

With the foreach binding that is provided out of the box in Knockout, I would have to divide my food in 3 arrays. If not, it would not be possible to add a divider per category.

function FoodViewModel(name, category, image) {
    var self = this;

    self.name = name;
    self.category = category;
    self.image = image;
};

function MainViewModel() {
    var self = this;

    self.fruit = ko.observableArray([
        new FoodViewModel("Apple", "Fruit", "/Images/apple.jpg"),
        new FoodViewModel("Banana", "Fruit", "/Images/banana.jpg"),
        new FoodViewModel("Pear", "Fruit", "/Images/pear.jpg")
    ]);

    self.vegetables = ko.observableArray([
        new FoodViewModel("Carrot", "Vegetables", "/Images/carrot.jpg"),
        new FoodViewModel("Tomato", "Vegetables", "/Images/tomato.jpg"),
    ]);

    self.snacks = ko.observableArray([
        new FoodViewModel("Cookie", "Snacks", "/Images/cookie.jpg")
    ]);
};
<ul data-role="listview" data-divider-theme="b">
    <li data-role="list-divider">Vegetables</li>
    <!-- ko foreach: vegetables -->
    <li>
        <a href="#">
            <img data-bind="attr: { src: image }" />
            <h3 data-bind="text: name"></h3>
        </a>
    </li>
    <!-- /ko -->

    <li data-role="list-divider">Fruit</li>
    <!-- ko foreach: fruit -->
    <li>
        <a href="#">
            <img data-bind="attr: { src: image }" />
            <h3 data-bind="text: name"></h3>
        </a>
    </li>
    <!-- /ko -->

    <li data-role="list-divider">Snacks</li>
    <!-- ko foreach: snacks -->
    <li>
        <a href="#">
            <img data-bind="attr: { src: image }" />
            <h3 data-bind="text: name"></h3>
        </a>
    </li>
    <!-- /ko -->
</ul>

I found this quite limiting, because I preferred to have one list containing all my food.

The jqmListView custom binding

In order to resolve this issue, I decided to develop a custom binding for the jQuery Mobile ListView. I based myself on the source of the foreach binding and customized it to have support for the features of the ListView.

It can be applied in two ways:

  1. <ul data-role=”listview” data-divider-theme=”b” data-bind=”jqmListView: food”>
  2. <ul data-role=”listview” data-divider-theme=”b” data-bind=”jqmListView: { data: food, divider: generateDivider, dividerCompareFunction: sortFood, itemCompareFunction: sortItems }”>

The properties “divider”, “dividerCompareFunction” and “itemCompareFunction” are optional.

divider

The property “divider” allows to customize the generation of the dividers for the ListView. It can be assigned a function that will called for every item in the list bound to the ListView. The function must return the category name for each item.

An example:

self.generateDivider = function (data) {
	return data.category;
};

dividerCompareFunction

The property “dividerCompareFunction” allows to customize the sorting of the dividers. By default they are sorted alphabetically.

An example:

self.sortFood = function (divider1, divider2) {
	var weights = new Object;
	weights["Vegetables"] = 1;
	weights["Fruit"] = 2;
	weights["Snacks"] = 3;

	return weights[divider1] - weights[divider2];
};

itemCompareFunction

The property “itemCompareFunction” allows to customize the sorting of the items of a given category. By default they are not sorted in order of appearance in the JavaScript list.

An example:

self.sortItems = function (item1, item2) {
	return item1.name.localeCompare(item2.name);
}

Sample Code

If we use the jqmListView binding, we can rewrite our sample application:

function FoodViewModel(name, category, image) {
    var self = this;

    self.name = name;
    self.category = category;
    self.image = image;
};

function MainViewModel() {
    var self = this;

    self.food = ko.observableArray([
        new FoodViewModel("Carrot", "Vegetables", "/Images/carrot.jpg"),
        new FoodViewModel("Apple", "Fruit", "/Images/apple.jpg"),
        new FoodViewModel("Pear", "Fruit", "/Images/pear.jpg"),
        new FoodViewModel("Tomato", "Vegetables", "/Images/tomato.jpg"),
        new FoodViewModel("Banana", "Fruit", "/Images/banana.jpg"),
        new FoodViewModel("Cookie", "Snacks", "/Images/cookie.jpg")
    ]);

    self.generateDivider = function (data) {
        return data.category;
    };

    self.sortFood = function (divider1, divider2) {
        var weights = new Object;
        weights["Vegetables"] = 1;
        weights["Fruit"] = 2;
        weights["Snacks"] = 3;

        return weights[divider1] - weights[divider2];
    };

    self.sortItems = function (item1, item2) {
        return item1.name.localeCompare(item2.name);
    }
};
<ul data-role="listview" data-divider-theme="b" data-bind="jqmListView: { data: food, divider: generateDivider, dividerCompareFunction: sortFood, itemCompareFunction: sortItems }">
    <li>
        <a href="#">
            <img data-bind="attr: { src: image }" />
            <h3 data-bind="text: name"></h3>
        </a>
    </li>
</ul>

The food sample application is a very simple application were the differences between the foreach and the jqmListView bindings are minor. But the jqmListView is a lot more flexible then the foreach binding in more complex cases. For example: if the data is coming from the server using a REST call and we don’t know beforehand all the available categories that will send to the browser.

You can download the sample from: http://sdrv.ms/Ol0LRY

jqmListView Code

Below you can find the source code  of my jqmListView binding. I will also upload this to GitHub.

(function () {
    ko.bindingHandlers.jqmListView = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            // Support anonymous templates
            var bindingValue = ko.utils.unwrapObservable(convertToBindingValue(valueAccessor));

            if ((element.nodeType == 1 || element.nodeType == 8)) {
                // It's an anonymous template - store the element contents, then clear the element
                var templateNodes = element.nodeType == 1 ? element.childNodes : ko.virtualElements.childNodes(element),
                    container = ko.utils.moveCleanedNodesToContainerElement(templateNodes); // This also removes the nodes from their current parent
                new ko.templateSources.anonymousTemplate(element)['nodes'](container);
            }
            return { 'controlsDescendantBindings': true };
        },
        update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var bindingValue = ko.utils.unwrapObservable(convertToBindingValue(valueAccessor));

            // Clean the current children
            $(element).empty();

            var dataArray = (bindingValue['data']) || [];
            var dividerFor = bindingValue['divider'];

            var dividerDictionary = new Object();
            for (var i = 0; i < dataArray.length; i++) {
                var dividierName = dividerFor(dataArray[i]);

                dividerDictionary[dividierName] = (dividerDictionary[dividierName]) || [];
                dividerDictionary[dividierName].push(dataArray[i]);
            }

            $.each(sortKeys(dividerDictionary, bindingValue.dividerCompareFunction), function (index, key) {
                if (key !== "") {
                    $(element).append('<li data-role="list-divider">' + key + '</li>');
                }

                var tempElement = document.createElement("div"); // Create temp DOM element to render templating
                ko.renderTemplateForEach(element, dividerDictionary[key].sort(bindingValue.itemCompareFunction), /* options: */bindingValue, tempElement, bindingContext);
                $(element).append($(tempElement).children()); // Add data to listview
            });

            $(element).listview('refresh');
        }
    };

    function convertToBindingValue(valueAccessor) {
        /// <summary>Standardizes the properties of the of the valueAccessor object.</summary>
        /// <returns>An object containing standardized binding properties.</returns>

        var bindingValue = ko.utils.unwrapObservable(valueAccessor());

        // If bindingValue is the array, just pass it on its own
        if ((!bindingValue) || typeof bindingValue.length == 'number')
            return {
                'data': bindingValue,
                'divider': function () { return ""; },
                'templateEngine': ko.nativeTemplateEngine.instance
            };

        // If bindingValue.data is the array, preserve all relevant options
        return {
            'data': ko.utils.unwrapObservable(bindingValue['data']),
            'divider': bindingValue['divider'] || function () { return ''; },
            'dividerCompareFunction': bindingValue['dividerCompareFunction'],
            'itemCompareFunction': bindingValue['itemCompareFunction'],
            'includeDestroyed': bindingValue['includeDestroyed'],
            'afterAdd': bindingValue['afterAdd'],
            'beforeRemove': bindingValue['beforeRemove'],
            'afterRender': bindingValue['afterRender'],
            'templateEngine': ko.nativeTemplateEngine.instance
        };
    };

    function sortKeys(data, compareFunction) {
        /// <summary>Convert the properties of a given object to an array and return them in sorted order.</summary>
        /// <param name="data">The object who's properties must be sorted.</param>
        /// <param name="compareFunction">The compare function that must be used during sorting.</param>
        /// <returns type="Array">The sorted properties of the object.</returns>

        var keys = Array();

        for (var key in data) {
            keys.push(key);
        }

        return keys.sort(compareFunction);
    }
})();
Categories: jQuery, MVVM

My MVVM tombstone pattern

August 25, 2011 4 comments

I am developing an application for Windows Phone 7 and during tombstoning I had to store some data of the view model. Tombstoning is done in the code behind of the view in the “OnNavigatedFrom” and “OnNavigatedTo” methods. This forced me to tightly couple my view model to (the code behind of) my view. As I don’t want this tightly coupling, I came with the following pattern:

Properties in the view model that must be tomstoned are decorated with the “Tombstone” attribute.

[Tombstone]
public SomeSerializableType SomeProperty { get; set; }

All my view then has to contain is the following code.

public MyPage()
{
    // ...
    isNewPage = true;
}

Please note: we need the “isNewPage” variable to differentiate between restoring a tombstoned view or revisiting the view in the current application instance.

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    if (isNewPage)
    {
        TombstoneHelper.RestoreState(this);

        isNewPage = false;
    }
}

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);

    TombstoneHelper.SaveState(this);
}

TombstoneHelper uses reflection to find all properties that must be tombstoned. It can be used with any view model and it allows my view models and views to be loosely coupled. The only drawback is that it can only be used for properties with public getters and setters, because reflection on WP7 does not allow developers to access private properties or variables.

/// <summary>
/// Attribute to indicate the ViewModel Property should be tombstoned.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class TombstoneAttribute : Attribute
{
}
public static class TombstoneHelper
{
    public static void SaveState(PhoneApplicationPage page)
    {
        foreach (PropertyInfo tombstoneProperty in FindTombstoneProperties(page.DataContext))
        {
            page.State["ViewModel." + tombstoneProperty.Name] = tombstoneProperty.GetValue(page.DataContext, null);
        }
    }

    public static void RestoreState(PhoneApplicationPage page)
    {
        foreach (PropertyInfo tombstoneProperty in FindTombstoneProperties(page.DataContext))
        {
            string key = "ViewModel." + tombstoneProperty.Name;

            if (page.State.ContainsKey(key))
            {
                tombstoneProperty.SetValue(page.DataContext, page.State[key], null);
            }
        }
    }

    // ...

    private static IEnumerable<PropertyInfo> FindTombstoneProperties(object o)
    {
        IList<PropertyInfo> tombstoneProperties = (from p in o.GetType().GetProperties()
                                                        where p.GetCustomAttributes(typeof(TombstoneAttribute), false).Length > 0
                                                        select p).ToList();

        foreach (PropertyInfo tombstoneProperty in tombstoneProperties)
        {
            if (!tombstoneProperty.CanRead || !tombstoneProperty.CanWrite)
            {
                throw new TombstoneException("The getter and the setter of a property that needs to be tomstoned must be declared public.");
            }
        }

        return tombstoneProperties;
    }
}

I also use TomstoneUtility to help tombstoning my controls. I will write more about this in a future blog article.

Frameworks used inside my WP7 application

August 19, 2011 2 comments

A couple of days ago, I have released the first version of my free open source WP7 application “Cloud Fox” to the windows phone market place. It allows Windows Phone 7 users to synchronize their FireFox bookmarks, history and open tabs with their mobile phone.

Developing it was a fun and interesting exercise. I was able to use some of the best .Net open source frameworks available. They allowed me to reduce the development time and they helped me improving the overall quality and user experience.

I wrote this article because I want to share these frameworks with fellow WP7 developers:

  • MVVM Light: One of the best MVVM frameworks available.
  • JSON.Net: Makes parsing JSON data very easy and it is much more standard-compliant then the Microsoft JSON parser.
  • Silverlight Toolkit for Windows Phone: Offers a lot of high quality Silverlight controls. I used the ToggleSwitch implementation.
  • Coding4Fun Windows Phone Toolkit: For the ToastPrompt control.
  • Prism: For the ApplicationBarButtonCommand component, allowing me to bind commands to the application bar buttons
  • Ninject: For gluing everything together 🙂

And a special thanks to NuGet; it made downloading and installing .Net libraries super easy.

Which .Net frameworks are you using for WP7 development? I’d love to know them! 🙂

Dynamically adding RaisePropertyChanged to MVVM Light ViewModels using Microsoft Unity

July 28, 2011 3 comments

Introduction

In the past, I already wrote two articles about dynamically adding RaisePropertyChanged support to view models. Today, I will explain how this can be accomplished with the IoC container: Microsoft Unity. Unity has out of the box support for AOP. Using Unity is much easier than my two previous do-it-yourselves ways. For real applications, I recommend using Unity or similar frameworks!

Like in my previous articles, I want to write view models using the following code pattern:

[RaisePropertyChanged]
public virtual string SomeProperty { get; set; }

Instead of the standard pattern:

private string someProperty;

public string SomeProperty
{
    get
    {
        return someProperty;
    }
    set
    {
        someProperty = value;
        RaisePropertyChanged("SomeProperty");
    }
}

Implementation

In order to get started, the first thing we have to do is install both Unity and MVVM Light. To do this, I recommend using Nuget. In the official Nuget repository, Unity is split into two packages. For the AOP support, both packages need to be added to the Visual Studio project.

nuget_Unity

Now that we have all the required libraries, we can start coding. First, lets define our RaisePropertyChangedAttribute class.

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class RaisePropertyChangedAttribute : HandlerAttribute
{
    public override ICallHandler CreateHandler(IUnityContainer container)
    {
        return new RaisePropertyChangedCallHandler();
    }
}

Because we want Unity to intercept calls, we must extend our attribute from HandlerAttribute. A custom HandlerAttribute must create and return a custom ICallHandler instance. We will return an instance of our custom RaisePropertyChangedCallHandler that we will create next.

Before writing our ICallHander, we must first look at the MSIL code generated by the C# compiler in order to understand .Net properties better. When a property is defined, 2 hidden methods are automatically created by the compiler; a get method and a set method. These methods have by default the name get_<property name> and set_<property name>.

Ildasm_property

With this knowledge in mind, the custom ICallHandler implementation is straightforward. We ask Unity to call the original set method and after its invocation we extract the name of property out of the name of the set method and we invoke the RaisePropertyChanged method of MVVM Light using reflection.

class RaisePropertyChangedCallHandler : ICallHandler
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        IMethodReturn methodReturn = getNext()(input, getNext);

        string propertyName = input.MethodBase.Name.Substring(4);

        MethodInfo raisePropertyChangedMethod = input.Target.GetType().GetMethod("RaisePropertyChanged",
            BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] {typeof(string)}, null);
        raisePropertyChangedMethod.Invoke(input.Target, new object[] { propertyName });

        return methodReturn;
    }

    public int Order { get; set; }
}

Configuring Unity

All that now remains is configuring Unity for our view model and activating virtual method AOP support for it. In code, we can define this using the following code sample:

IUnityContainer container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterType<SampleViewModel>().
    Configure<Interception>().
    SetInterceptorFor<SampleViewModel>(new VirtualMethodInterceptor());

If we now use Unity for creating instances of our sample view model class, all the properties annotated with “RaisePropertyChanged” will atomically be “property change”-aware.

SampleViewModel vm = container.Resolve<SampleViewModel>();

Please note: This will not work in Silverlight, because of limitations in its runtime. (Silverlight does not allow the invocation of private methods using reflection for security reasons)

Categories: C#, IoC, MVVM, WPF Tags: , , , ,

Dynamically adding RaisePropertyChanged to MVVM Light ViewModels using Mono Cecil

July 13, 2011 3 comments

Introduction

A few days ago, I wrote an article about dynamically modifying MVVM Light ViewModels using Reflection.Emit. The same can be done with the more powerful Mono Cecil library. Mono Cecil can both create assemblies at runtime and modify existing ones. The latter allows to modify post-compilation the generated MSIL code. This is helpful on platforms like Windows Phone 7; that do not allow dynamic runtime loading of assemblies.

In this article, I will show you how we can generate the same proxies as in the Reflection.Emit example. In a latter example, I will show you how to update assemblies post compilation for use on Windows Phone 7. If you have not read my previous article, I recommend that you read it first.

Implementation

Mono Cecil can be easily retrieved using NuGet.

mono_cecil_nuget

The implementation is almost the same; similar concepts classes are used. I will not explain them in detail, but just show the modified example. (If you would have questions, feel free to drop a comment Glimlach).

public static class CecilViewModelFactory
{
    public static T CreateInstance<T>()
        where T : ViewModelBase
    {
        Type vmType = typeof(T);

        ModuleDefinition module = ModuleDefinition.CreateModule("CecilDynamicTestPieter", ModuleKind.Dll);
        TypeReference baseTypeReference = module.Import(vmType);
        TypeDefinition typeDefinition =
            new TypeDefinition(vmType.Namespace, "Smart" + vmType.Name, TypeAttributes.Public, baseTypeReference);
        module.Types.Add(typeDefinition);
        MethodReference raisePropertyChangedMethod = module.Import(typeof(ViewModelBase).GetMethod("RaisePropertyChanged",
            Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance, null, new Type[] { typeof(string) }, null));

        // Create default constructor
        typeDefinition.Methods.Add(CreateDefaultConstructor(module, vmType));

        foreach (Reflection.PropertyInfo propertyInfo in FindNotifyPropertyChangCandidates<T>())
        {
            ILProcessor processor;

            // Get set method of base type
            MethodReference setMethodReference = module.Import(propertyInfo.GetSetMethod());

            PropertyDefinition propertyDefinition = new PropertyDefinition(propertyInfo.Name,
                PropertyAttributes.None, module.Import(propertyInfo.PropertyType));
            typeDefinition.Properties.Add(propertyDefinition);

            // Create set method
            MethodDefinition setMethodDefinition = new MethodDefinition("set_" + propertyInfo.Name,
                MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Virtual,
                module.Import(typeof(void)));
            setMethodDefinition.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, module.Import(propertyInfo.PropertyType)));
            propertyDefinition.SetMethod = setMethodDefinition;
            typeDefinition.Methods.Add(setMethodDefinition);

            processor = setMethodDefinition.Body.GetILProcessor();

            // Add IL code for set method
            processor.Emit(OpCodes.Nop);
            processor.Emit(OpCodes.Ldarg_0);
            processor.Emit(OpCodes.Ldarg_1);
            processor.Emit(OpCodes.Call, setMethodReference);

            // Call property changed for object
            processor.Emit(OpCodes.Nop);
            processor.Emit(OpCodes.Ldarg_0);
            processor.Emit(OpCodes.Ldstr, propertyInfo.Name);
            processor.Emit(OpCodes.Callvirt, raisePropertyChangedMethod);
            processor.Emit(OpCodes.Nop);
            processor.Emit(OpCodes.Ret);
        }

        return CreateInstance<T>(module, typeDefinition);
    }

    private static MethodDefinition CreateDefaultConstructor(ModuleDefinition module, Type baseType)
    {
        MethodDefinition defaultConstructor =
            new MethodDefinition(".ctor",
                MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                module.Import(typeof(void)));
        ILProcessor processor = defaultConstructor.Body.GetILProcessor();
        processor.Emit(OpCodes.Ldarg_0);
        processor.Emit(OpCodes.Call, module.Import(baseType.GetConstructor(Type.EmptyTypes)));
        processor.Emit(OpCodes.Ret);

        return defaultConstructor;
    }

    private static IEnumerable<Reflection.PropertyInfo> FindNotifyPropertyChangCandidates<T>()
    {
        return from p in typeof(T).GetProperties()
                where p.GetSetMethod() != null && p.GetSetMethod().IsVirtual &&
                p.GetCustomAttributes(typeof(RaisePropertyChangedAttribute), false).Length > 0
                select p;
    }
}

Note: The issue I had when started using Mono Cecil, was how to load assemblies dynamically; instead of just writing them to disk. At the end, I came up with this solution.

private static T CreateInstance<T>(ModuleDefinition module, TypeDefinition typeDefinition)
{
    Type dynamicType;

    using (MemoryStream stream = new MemoryStream())
    {
        module.Write(stream);
        Reflection.Assembly assembly = Reflection.Assembly.Load(stream.ToArray());
        dynamicType = assembly.GetType(typeDefinition.FullName);
    }
    return (T)Activator.CreateInstance(dynamicType);
}

Using the CecilViewModelFactory implementation is very straightforward; dynamic ViewsModels can be created using the following pattern:

SampleViewModel viewModel = CecilViewModelFactory.CreateInstance<SampleViewModel>();

Conclusion

In this article, I have just shown the top of the iceberg of what is possible with Mono Cecil. Dynamically creating or modifying types can reduce boiler code and lead to cleaner code. I a next article, I plan to show how you can use this in WP7 applications.

Categories: C#, MVVM, Silverlight, WPF

Dynamically adding RaisePropertyChanged to MVVM Light ViewModels using Reflection.Emit

July 8, 2011 10 comments

Introduction

I like the clean separation between views and view models made possible by the MVVM pattern. But I don’t like the code pattern required to implement RaisePropertyChanged in simple properties.

private static string someProperty;

public string SomeProperty
{
    get
    {
        return someProperty;
    }
    set
    {
        someProperty = value;
        RaisePropertyChanged("SomeProperty");
    }
}

I would prefer an implementation like this:

[RaisePropertyChanged]
public string SomeProperty { get; set; }

Implementing this is possible with a principle called AOP (Aspect Oriented Programming). Although C# is an OOP (Object Oriented Programming) language, various people and companies have made AOP in C# easily possible. As I am a passionate technologist, I off course wanted to understand how this “magic” works Glimlach.

Two options are possible: post compilation by modifying the compiled assemblies or dynamic creation of proxy classes at runtime. In this article, I will present how you can implement this yourself. But because various high quality tools and frameworks are available, I recommend not to implement this yourself for production code.

Post compilation can be done by an AOP tool like PostSharp. Dynamic proxy creation is done by libraries such as Castle DynamicProxy or by IOC containers like Microsoft Unity.

Dynamic proxy Creation

I have chose to use dynamic proxy creation in my example. I will not make my code generic, but instead I will hardcode the required functionality. I assume that you will be capable of generalizing this yourself, if required. The code relies on MVVM Light, but you could replace this library with any other MVVM library.

The API that allows this dynamic behavior is Reflection.Emit and it allows you to create classes at runtime using MSIL code. MSIL is the assembly of the .Net CLR. Most .Net programmers have probably never seen this language. By using a smart trick, only a limited knowledge is required.

Microsoft has an MSIL disassembler called “ILDASM”. You can use this tool easily if you launch it from the “Visual Studio 2010 command prompt”. To know the required MSIL code for our prototype, we first create what we want in c#, compile it and then look at the generated MSIL code with ILDASM.

The proxy we want to create dynamically (SampleViewModelExtended) looks like:

// Dynamic proxy created manually
public class SampleViewModelExtended : SampleViewModel
{
    public override string SomeProperty
    {
        get
        {
            return base.SomeProperty;
        }
        set
        {
            base.SomeProperty = value;
            RaisePropertyChanged("SomeProperty");
        }
    }
}

public class SampleViewModel : ViewModelBase
{
    [RaisePropertyChanged]
    public virtual string SomeProperty { get; set; }
}

Please note: we have to make the properties virtual in the base class, because otherwise we cannot overwrite the setters in the derived class.

If we compile this and look at the MSIL, we get:

ILDASM_required_MSIL_code

Having the required MSIL code, the only thing we now have to do is generating the MSIL dynamically using Reflection.Emit.

public static class ReflectionEmitViewModelFactory
{
    public static T CreateInstance<T>()
        where T : ViewModelBase
    {
        Type vmType = typeof(T);

        VerifyViewModelType(vmType);

        // Create everything required to get a module builder
        AssemblyName assemblyName = new AssemblyName("SmartViewModelDynamicAssembly");
        AppDomain domain = AppDomain.CurrentDomain;
        AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            //AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name);

        string dynamicTypeName = Assembly.CreateQualifiedName(vmType.AssemblyQualifiedName, "Smart" + vmType.Name);

        TypeBuilder typeBuilder = moduleBuilder.DefineType(dynamicTypeName,
            TypeAttributes.Public | TypeAttributes.Class, vmType);

        MethodInfo raisePropertyChangedMethod = typeof(ViewModelBase).GetMethod("RaisePropertyChanged",
            BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string) }, null);

        foreach (PropertyInfo propertyInfo in FindNotifyPropertyChangCandidates<T>())
            UpdateProperty(propertyInfo, typeBuilder, raisePropertyChangedMethod);

        Type dynamicType = typeBuilder.CreateType();

        return (T)Activator.CreateInstance(dynamicType);
    }

    private static void VerifyViewModelType(Type vmType)
    {
        if (vmType.IsSealed)
            throw new InvalidOperationException("The specified view model type is not allowed to be sealed.");
    }

    private static IEnumerable<PropertyInfo> FindNotifyPropertyChangCandidates<T>()
    {
        return from p in typeof(T).GetProperties()
                where p.GetSetMethod() != null && p.GetSetMethod().IsVirtual &&
                p.GetCustomAttributes(typeof(RaisePropertyChangedAttribute), false).Length > 0
                select p;
    }

    private static void UpdateProperty(PropertyInfo propertyInfo, TypeBuilder typeBuilder,
        MethodInfo raisePropertyChangedMethod)
    {
        // Update the setter of the class
        PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyInfo.Name,
            PropertyAttributes.None, propertyInfo.PropertyType, null);

        // Create set method
        MethodBuilder builder = typeBuilder.DefineMethod("set_" + propertyInfo.Name,
            MethodAttributes.Public | MethodAttributes.Virtual, null, new Type[] { propertyInfo.PropertyType });
        builder.DefineParameter(1, ParameterAttributes.None, "value");
        ILGenerator generator = builder.GetILGenerator();

        // Add IL code for set method
        generator.Emit(OpCodes.Nop);
        generator.Emit(OpCodes.Ldarg_0);
        generator.Emit(OpCodes.Ldarg_1);
        generator.Emit(OpCodes.Call, propertyInfo.GetSetMethod());

        // Call property changed for object
        generator.Emit(OpCodes.Nop);
        generator.Emit(OpCodes.Ldarg_0);
        generator.Emit(OpCodes.Ldstr, propertyInfo.Name);
        generator.Emit(OpCodes.Callvirt, raisePropertyChangedMethod);
        generator.Emit(OpCodes.Nop);
        generator.Emit(OpCodes.Ret);
        propertyBuilder.SetSetMethod(builder);
    }
}

Once you know the MSIL to generate, using Reflection.Emit is very straightforward. By using the sample code provided above, we can know create dynamic ViewsModels very easy:

SampleViewModel viewModel = ReflectionEmitViewModelFactory.CreateInstance<SampleViewModel>();