Monday, March 09, 2009

Dynamic Interface Addition to existing Class using Reflection

I recently went through an article by Eric McMullen. The power of reflection and dynamic code was so well depicted in the article.

We know how to create a dynamic code using reflection. But what i liked about this bit of article from Eric was how an already existing type was wrapped by a Interface dynamically at the runtime. Now, isn't that a useful feature to have ??

Not sure ?? Think in this manner. You have an interface with a method "Name". You also have a class "MyName" which DOES NOT implement the interface but has a virtual method "Name". It is obvious that you cannt create a referance of the interface for the class. But the point , is with Dynamic extension, we could just well do it.

How do we do it ? lets have a look at the code.

First and foremost thing you would want is have an assembly, in this case a dynamic one. So let us go ahead and degfine it first.

I have create a function which would take the target type and interface that needs to be implement as parameters.

public object GetNewImplementation(System.Type TargetType,System.Type InterfaceToImplement)
AssemblyName an = new AssemblyName();
an.Name = "ExtendedTypes";
assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler ( CurrentDomain_AssemblyResolve);
Type t = Subclass (moduleBuilder, TargetType, InterfaceToImplement, "ClassTest1");
return (Activator.CreateInstance(t,true)) as object;

As you can see i am calling a SubClass method in later part of the method. This is the magic method which does the trick for us.

public Type Subclass(ModuleBuilder builder, Type target, Type interfaceToImplement, string newTypeName)
TypeAttributes attributes = TypeAttributes.Public;

TypeBuilder tb =builder.DefineType("ConsoleApplication1.DynamicClassTest1", attributes,target);

Type subClass = tb.CreateType();
return subClass;

private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
Assembly returnVal = null;
if(args.Name == this.assemblyBuilder.FullName)
returnVal = assemblyBuilder;
return returnVal;

Now is that cool ?