I am trying to create a proxy class dynamically. I know there are some very good frameworks out there to do this but this is purely a pet project as a learning exercise so
I wouldn't recommend doing this. Usually you use some well-known libraries such as Castle or EntLib. For some complicated classes it could be quite a challenge to dynamically generate a proxy. Here is an example of doing that using "Is" polymorphism. For this you have to declare all your methods in base as virtual. The way you were trying to do this ("Has") also possible, but for me looks more complicated.
public class A
{
public virtual void B()
{
Console.WriteLine("Original method was called.");
}
}
class Program
{
static void Main(string[] args)
{
// Create simple assembly to hold our proxy
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "DynamicORMapper";
AppDomain thisDomain = Thread.GetDomain();
var asmBuilder = thisDomain.DefineDynamicAssembly(assemblyName,
AssemblyBuilderAccess.Run);
var modBuilder = asmBuilder.DefineDynamicModule(
asmBuilder.GetName().Name, false);
// Create a proxy type
TypeBuilder typeBuilder = modBuilder.DefineType("ProxyA",
TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout,
typeof(A));
MethodBuilder methodBuilder = typeBuilder.DefineMethod("B", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot);
typeBuilder.DefineMethodOverride(methodBuilder, typeof(A).GetMethod("B"));
// Generate a Console.Writeline() and base.B() calls.
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.EmitWriteLine("We caught an invoke! B method was called.");
ilGenerator.EmitCall(OpCodes.Call, typeBuilder.BaseType.GetMethod("B"), new Type[0]);
ilGenerator.Emit(OpCodes.Ret);
//Create a type and casting it to A.
Type type = typeBuilder.CreateType();
A a = (A) Activator.CreateInstance(type);
// Test it
a.B();
Console.ReadLine();
}
}