private static void CreateProperty(TypeBuilder tb, FieldBuilder fbInstance, PropertyInfo pi, MethodInfoHolder getMi, MethodInfoHolder setMi) { var name = pi.Name; var type = pi.PropertyType; var pb = tb.DefineProperty(name, PropertyAttributes.HasDefault, type, null); var getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final; var mbGetAccessor = tb.DefineMethod("get_" + name, getSetAttr, type, Type.EmptyTypes); var getIL = mbGetAccessor.GetILGenerator(); if (getMi == null) { getIL.Emit(OpCodes.Newobj, typeof(NotImplementedException).GetConstructor(new Type[] { })); getIL.Emit(OpCodes.Throw); } else { getIL.Emit(OpCodes.Ldarg_0); getIL.Emit(OpCodes.Ldfld, fbInstance); getIL.Emit(OpCodes.Ldc_I4, getMi.ObjectIndex); getIL.Emit(OpCodes.Callvirt, ObjectContainer.GetGetMethodInfo()); getIL.Emit(OpCodes.Isinst, getMi.ObjectType); getIL.Emit(OpCodes.Callvirt, getMi.MethodInfo); getIL.Emit(OpCodes.Ret); } var mbSetAccessor = tb.DefineMethod("set_" + name, getSetAttr, null, new Type[] { type }); var setIL = mbSetAccessor.GetILGenerator(); if (setMi == null) { setIL.Emit(OpCodes.Newobj, typeof(NotImplementedException).GetConstructor(new Type[] { })); setIL.Emit(OpCodes.Throw); } else { setIL.Emit(OpCodes.Ldarg_0); setIL.Emit(OpCodes.Ldfld, fbInstance); setIL.Emit(OpCodes.Ldc_I4, setMi.ObjectIndex); setIL.Emit(OpCodes.Callvirt, ObjectContainer.GetGetMethodInfo()); setIL.Emit(OpCodes.Isinst, setMi.ObjectType); setIL.Emit(OpCodes.Ldarg_1); setIL.Emit(OpCodes.Callvirt, setMi.MethodInfo); setIL.Emit(OpCodes.Ret); } pb.SetGetMethod(mbGetAccessor); pb.SetSetMethod(mbSetAccessor); }
private static void CreateMethod(TypeBuilder tb, FieldBuilder fbInstance, MethodInfo mi, MethodInfoHolder instanceMi) { var paramTyleList = new List <Type>(); foreach (var item in mi.GetParameters()) { paramTyleList.Add(item.ParameterType); } var mb = tb.DefineMethod(mi.Name, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, mi.ReturnType, paramTyleList.ToArray()); var il = mb.GetILGenerator(); if (instanceMi == null) { il.Emit(OpCodes.Newobj, typeof(NotImplementedException).GetConstructor(new Type[] { })); il.Emit(OpCodes.Throw); } else { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, fbInstance); il.Emit(OpCodes.Ldc_I4, instanceMi.ObjectIndex); il.Emit(OpCodes.Callvirt, ObjectContainer.GetGetMethodInfo()); il.Emit(OpCodes.Isinst, instanceMi.ObjectType); switch (paramTyleList.Count) { case 0: break; case 1: il.Emit(OpCodes.Ldarg_1); break; case 2: il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); break; case 3: il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldarg_3); break; default: il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldarg_3); var sCount = Math.Min(paramTyleList.Count, 127); for (int i = 4; i <= sCount; i++) { il.Emit(OpCodes.Ldarg_S, i); } for (int i = 128; i <= paramTyleList.Count; i++) { il.Emit(OpCodes.Ldarg, i); } break; } il.Emit(OpCodes.Callvirt, instanceMi.MethodInfo); il.Emit(OpCodes.Ret); } }
public static Type DynamicTypeGen <TInterface>(Object[] instances, Type[] typeList) where TInterface : class { Type tInterface = typeof(TInterface); PropertyInfo[] pisInterface = tInterface.GetProperties(BindingFlags.Public | BindingFlags.Instance); MethodInfo[] misInterface = tInterface.GetMethods(BindingFlags.Public | BindingFlags.Instance); List <MethodInfo> misInterfaceList = new List <MethodInfo>(); List <Type> tList = new List <Type>(); foreach (var obj in instances) { tList.Add(obj.GetType()); } Type[] tArray = tList.ToArray(); foreach (var item in misInterface) { if (item.IsSpecialName == false) { misInterfaceList.Add(item); } } List <MethodInfoHolder> miHolderList = new List <MethodInfoHolder>(); for (int i = 0; i < tArray.Length; i++) { MethodInfo[] misImple = tArray[i].GetMethods(BindingFlags.Public | BindingFlags.Instance); foreach (var item in misImple) { MethodInfoHolder h = new MethodInfoHolder(item, i, typeList[i]); miHolderList.Add(h); } } AssemblyName aName = new AssemblyName("Orc.Generics.DynamicTypes"); AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly( aName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll"); TypeBuilder tb = mb.DefineType(GetDynamicTypeName <TInterface>(instances), TypeAttributes.Public, null, new Type[] { tInterface }); FieldBuilder fbInstances = tb.DefineField( "_container", typeof(TypeTemplate.ObjectContainer), FieldAttributes.Private); ConstructorBuilder ctor1 = tb.DefineConstructor( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName, CallingConventions.Standard, new Type[1] { typeof(TypeTemplate.ObjectContainer) }); ILGenerator ctor1IL = ctor1.GetILGenerator(); ctor1IL.Emit(OpCodes.Ldarg_0); ctor1IL.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); ctor1IL.Emit(OpCodes.Ldarg_0); ctor1IL.Emit(OpCodes.Ldarg_1); ctor1IL.Emit(OpCodes.Stfld, fbInstances); ctor1IL.Emit(OpCodes.Ret); foreach (var item in pisInterface) { MethodInfoHolder getMi = FindGetMethodInfo(miHolderList, item); MethodInfoHolder setMi = FindSetMethodInfo(miHolderList, item); CreateProperty(tb, fbInstances, item, getMi, setMi); } foreach (var item in misInterfaceList) { MethodInfoHolder instanceMi = FindMethodInfo(miHolderList, item); CreateMethod(tb, fbInstances, item, instanceMi); } Type type = tb.CreateType(); ab.Save(aName.Name + ".dll"); return(type); }