Over a million developers have joined DZone.

Dynamically adding RaisePropertyChanged to MVVM Light ViewModels using Mono Cecil

DZone 's Guide to

Dynamically adding RaisePropertyChanged to MVVM Light ViewModels using Mono Cecil

· ·
Free Resource


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.


Mono Cecil can be easily retrieved using 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);
        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));

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

            processor = setMethodDefinition.Body.GetILProcessor();

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

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

        return CreateInstance<T>(module, typeDefinition);

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

        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())
        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>();


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.


Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}