OK, here's a complete example that declares an interface in one
dynamic assembly, implements it in another, and then tests the
interface via reflection. It also saves both assemblies to disk so you
can load them in reflector/ildasm and verify that the references have
been set correctly (which they have, for me at least...):
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace ConsoleApplication3
{
class Program
{
static void Main()
{
AssemblyBuilder assembly =
AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName("Foo"),
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder module =
assembly.DefineDynamicModule("Foo.dll");
TypeBuilder tb = module.DefineType("IFoo",
TypeAttributes.Interface | TypeAttributes.Abstract |
TypeAttributes.Public);
PropertyBuilder prop = tb.DefineProperty("Message",
PropertyAttributes.None, typeof(string), Type.EmptyTypes);
MethodBuilder method = tb.DefineMethod("get_Message",
MethodAttributes.Public | MethodAttributes.HideBySig
| MethodAttributes.NewSlot | MethodAttributes.Abstract
| MethodAttributes.Virtual, CallingConventions.HasThis,
typeof(string), Type.EmptyTypes);
prop.SetGetMethod(method);
Type ifoo = tb.CreateType();
assembly.Save("Foo.dll");
assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName("Bar"),
AssemblyBuilderAccess.RunAndSave);
module = assembly.DefineDynamicModule("Bar.dll");
tb = module.DefineType("Bar", TypeAttributes.Class |
TypeAttributes.Sealed | TypeAttributes.Public);
tb.DefineDefaultConstructor(MethodAttributes.Public);
tb.AddInterfaceImplementation(ifoo);
MethodInfo interfaceMethod =
ifoo.GetMethod("get_Message");
method = tb.DefineMethod("MyMethodImpl",
MethodAttributes.Private | MethodAttributes.HideBySig
| MethodAttributes.NewSlot | MethodAttributes.Final |
MethodAttributes.Virtual | MethodAttributes.SpecialName
, CallingConventions.HasThis, typeof(string),
Type.EmptyTypes);
ILGenerator il = method.GetILGenerator();
il.Emit(OpCodes.Ldstr, "hello world");
il.Emit(OpCodes.Ret);
tb.DefineMethodOverride(method, interfaceMethod);
Type bar = tb.CreateType();
assembly.Save("Bar.dll");
typeof(Program).GetMethod("Test").MakeGenericMethod(ifoo,
bar).Invoke(null, null);
}
public static void Test<TInterface, TClass>()
where TInterface : class
where TClass : class, TInterface, new()
{
// create an instance
TClass obj = new TClass();
// check the cast (already validated by generic
constraint)
TInterface i = obj;
// try to read the property
PropertyInfo prop =
typeof(TInterface).GetProperty("Message");
object val = prop.GetValue(obj, null);
Console.WriteLine(val);
}
}
}