本文共 16294 字,大约阅读时间需要 54 分钟。
lock (handlers.SyncRoot)
{ AppDomain currentAppDomain = AppDomain.CurrentDomain; AssemblyName assyName = new AssemblyName(); assyName.Name = type.FullName; AssemblyBuilder assyBuilder = currentAppDomain.DefineDynamicAssembly(assyName, AssemblyBuilderAccess.Run); ModuleBuilder modBuilder = assyBuilder.DefineDynamicModule(type.FullName); Type[] newTypeInterfaces; newTypeInterfaces = new Type[] { typeof(IValueHandler) }; TypeBuilder typeBuilder = modBuilder.DefineType( "ValueHandler", TypeAttributes.Public);typeBuilder.AddInterfaceImplementation(typeof(IValueHandler));
//PropertyInfo[] infos tmpInfos PropertyInfo[] infos = type.GetProperties();
TypeBuilder pidBuilder =
modBuilder.DefineType( "<PrivateImplementationDetails>", TypeAttributes.AutoClass | TypeAttributes.AnsiClass); FieldBuilder getHashtableBuilder = pidBuilder.DefineField( "$$method0x6000022-1", typeof(Hashtable), FieldAttributes.Static | FieldAttributes.Assembly); FieldBuilder setHashtableBuilder = pidBuilder.DefineField( "$$method0x6000023-1", typeof(Hashtable), FieldAttributes.Static | FieldAttributes.Assembly); pidBuilder.CreateType();MethodBuilder createInstanceMethodBuilder = typeBuilder.DefineMethod(
"CreateInstance", MethodAttributes.Public | MethodAttributes.Virtual, typeof(object), null); ILGenerator createGenerator = createInstanceMethodBuilder.GetILGenerator(); createGenerator.DeclareLocal(typeof(object)); ConstructorInfo constructorInfo = type.GetConstructor(Type.EmptyTypes); if (constructorInfo != null) { Label createRet = createGenerator.DefineLabel(); createGenerator.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); createGenerator.Emit(OpCodes.Stloc_0); createGenerator.Emit(OpCodes.Br_S, createRet); createGenerator.MarkLabel(createRet); createGenerator.Emit(OpCodes.Ldloc_0); createGenerator.Emit(OpCodes.Ret); } else { createGenerator.Emit(OpCodes.Ldstr, "The object does not has default constructor"); createGenerator.Emit(OpCodes.Newobj, typeof(Exception).GetConstructor(new Type[] { typeof(string) })); createGenerator.Emit(OpCodes.Throw); }#region Get
MethodBuilder getMethodBuilder = typeBuilder.DefineMethod(
"GetValue", MethodAttributes.Public | MethodAttributes.Virtual, typeof(object), new Type[] { typeof(object), typeof(string) }); ILGenerator getGenerator = getMethodBuilder.GetILGenerator(); getGenerator.DeclareLocal(typeof(object)); getGenerator.DeclareLocal(typeof(object));Label L_0112 = getGenerator.DefineLabel();
Label L_0256 = getGenerator.DefineLabel(); Label getRet = getGenerator.DefineLabel(); Label L_0526 = getGenerator.DefineLabel(); Label L_054e = getGenerator.DefineLabel();ArrayList getLabelArr = new ArrayList();
for (int i = 0; i < infos.Length; i++) { try { MethodInfo minfo = type.GetMethod("get_" + infos[i].Name); if (minfo == null || minfo.GetParameters().Length > 0) continue; //忽略索引器getLabelArr.Add(getGenerator.DefineLabel());
} catch { } } Label[] getLabels = new Label[getLabelArr.Count]; getLabelArr.CopyTo(getLabels);getGenerator.Emit(OpCodes.Volatile);
getGenerator.Emit(OpCodes.Ldsfld, getHashtableBuilder); getGenerator.Emit(OpCodes.Brtrue, L_0112); getGenerator.Emit(OpCodes.Ldc_I4, infos.Length); getGenerator.Emit(OpCodes.Ldc_R4, .5F); getGenerator.Emit(OpCodes.Newobj, typeof(Hashtable).GetConstructor(new Type[] { typeof(Int32), typeof(Single) })); for (int i = 0, j = 0; i < infos.Length; i++) { try { MethodInfo minfo = type.GetMethod("get_" + infos[i].Name); if (minfo == null || minfo.GetParameters().Length > 0) continue; getGenerator.Emit(OpCodes.Dup); getGenerator.Emit(OpCodes.Ldstr, infos[i].Name); getGenerator.Emit(OpCodes.Ldc_I4_S, j++); getGenerator.Emit(OpCodes.Box, typeof(Int32)); getGenerator.Emit(OpCodes.Call, typeof(Hashtable).GetMethod("Add", new Type[] { typeof(object), typeof(object) })); } catch { } } getGenerator.Emit(OpCodes.Volatile); getGenerator.Emit(OpCodes.Stsfld, getHashtableBuilder); getGenerator.MarkLabel(L_0112); getGenerator.Emit(OpCodes.Ldarg_2); getGenerator.Emit(OpCodes.Dup); getGenerator.Emit(OpCodes.Stloc_1); getGenerator.Emit(OpCodes.Brfalse, L_0256); getGenerator.Emit(OpCodes.Volatile); getGenerator.Emit(OpCodes.Ldsfld, getHashtableBuilder); // [mscorlib]System.Collections.Hashtable <PrivateImplementationDetails>::$$method0x6000022-1 getGenerator.Emit(OpCodes.Ldloc_1); getGenerator.Emit(OpCodes.Call, typeof(Hashtable).GetMethod("get_Item", new Type[] { typeof(object) })); getGenerator.Emit(OpCodes.Dup); getGenerator.Emit(OpCodes.Stloc_1); getGenerator.Emit(OpCodes.Brfalse, L_0256); getGenerator.Emit(OpCodes.Ldloc_1); getGenerator.Emit(OpCodes.Unbox, typeof(Int32)); getGenerator.Emit(OpCodes.Ldind_I4); getGenerator.Emit(OpCodes.Switch, getLabels); getGenerator.Emit(OpCodes.Br, L_0256);for (int i = 0, j = 0; i < infos.Length; i++)
{ try { MethodInfo minfo = type.GetMethod("get_" + infos[i].Name); if (minfo == null || minfo.GetParameters().Length > 0) continue; getGenerator.MarkLabel(getLabels[j++]); getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.Emit(OpCodes.Castclass, type); getGenerator.Emit(OpCodes.Callvirt, minfo); if (infos[i].PropertyType.IsValueType) getGenerator.Emit(OpCodes.Box, infos[i].PropertyType); getGenerator.Emit(OpCodes.Stloc_0); getGenerator.Emit(OpCodes.Br, getRet); } catch { } }getGenerator.MarkLabel(L_0256);
if (type.BaseType == typeof(Array)) { getGenerator.Emit(OpCodes.Ldarg_2); getGenerator.Emit(OpCodes.Ldc_I4_0); getGenerator.Emit(OpCodes.Callvirt, typeof(string).GetMethod("get_Chars", new Type[] { typeof(Int32) })); getGenerator.Emit(OpCodes.Call, typeof(Char).GetMethod("IsDigit", new Type[] { typeof(Char) })); getGenerator.Emit(OpCodes.Brfalse_S, L_0526); getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.Emit(OpCodes.Castclass, typeof(object[])); getGenerator.Emit(OpCodes.Ldarg_2); getGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) })); getGenerator.Emit(OpCodes.Ldelem_Ref); getGenerator.Emit(OpCodes.Stloc_0); getGenerator.Emit(OpCodes.Br_S, getRet); getGenerator.MarkLabel(L_0526); } else { MethodInfo intIndexer = type.GetMethod("get_Item", new Type[] { typeof(Int32) }); //if index is object type, GetMethod will return indexer's MethodInfo whatever type I pass if (intIndexer != null && intIndexer.GetParameters()[0].ParameterType != typeof(object)) { getGenerator.Emit(OpCodes.Ldarg_2); getGenerator.Emit(OpCodes.Ldc_I4_0); getGenerator.Emit(OpCodes.Callvirt, typeof(string).GetMethod("get_Chars", new Type[] { typeof(Int32) })); getGenerator.Emit(OpCodes.Call, typeof(Char).GetMethod("IsDigit", new Type[] { typeof(Char) })); getGenerator.Emit(OpCodes.Brfalse_S, L_0526); getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.Emit(OpCodes.Castclass, type); getGenerator.Emit(OpCodes.Ldarg_2); getGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) })); getGenerator.Emit(OpCodes.Callvirt, intIndexer); getGenerator.Emit(OpCodes.Stloc_0); getGenerator.Emit(OpCodes.Br_S, getRet); getGenerator.MarkLabel(L_0526); }MethodInfo strIndexer = type.GetMethod("get_Item", new Type[] { typeof(string) });
if (strIndexer != null) { getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.Emit(OpCodes.Castclass, type); getGenerator.Emit(OpCodes.Ldarg_2); getGenerator.Emit(OpCodes.Callvirt, strIndexer); getGenerator.Emit(OpCodes.Stloc_0); getGenerator.Emit(OpCodes.Br_S, getRet); getGenerator.MarkLabel(L_054e); } }getGenerator.Emit(OpCodes.Ldstr, "The property named ");
getGenerator.Emit(OpCodes.Ldarg_2); getGenerator.Emit(OpCodes.Ldstr, " does not exists"); getGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string), typeof(string) })); getGenerator.Emit(OpCodes.Newobj, typeof(Exception).GetConstructor(new Type[] { typeof(string) })); getGenerator.Emit(OpCodes.Throw);getGenerator.MarkLabel(getRet);
getGenerator.Emit(OpCodes.Ldloc_0); getGenerator.Emit(OpCodes.Ret);#endregion
#region Set
MethodBuilder setMethodBuilder = typeBuilder.DefineMethod(
"SetValue", MethodAttributes.Public | MethodAttributes.Virtual, null , new Type[] { typeof(object), typeof(string), typeof(object) }); ILGenerator setGenerator = setMethodBuilder.GetILGenerator(); setGenerator.DeclareLocal(typeof(object));Label L_0220 = setGenerator.DefineLabel();
Label L_053b = setGenerator.DefineLabel(); Label L_0568 = setGenerator.DefineLabel(); Label L_0593 = setGenerator.DefineLabel(); Label setRet = setGenerator.DefineLabel();ArrayList setLabelList = new ArrayList();
for (int i = 0; i < infos.Length; i++) { try { MethodInfo minfo = type.GetMethod("set_" + infos[i].Name); if (minfo == null || minfo.GetParameters().Length > 1) continue; setLabelList.Add(setGenerator.DefineLabel()); } catch { } } Label[] setLabels = new Label[setLabelList.Count]; setLabelList.CopyTo(setLabels);setGenerator.Emit(OpCodes.Volatile);
setGenerator.Emit(OpCodes.Ldsfld, setHashtableBuilder); setGenerator.Emit(OpCodes.Brtrue, L_0220); setGenerator.Emit(OpCodes.Ldc_I4, infos.Length); setGenerator.Emit(OpCodes.Ldc_R4, 1F); setGenerator.Emit(OpCodes.Newobj, typeof(Hashtable).GetConstructor(new Type[] { typeof(Int32), typeof(Single) })); for (int i = 0, j = 0; i < infos.Length; i++) { MethodInfo minfo = type.GetMethod("set_" + infos[i].Name); if (minfo == null || minfo.GetParameters().Length > 1) continue; setGenerator.Emit(OpCodes.Dup); setGenerator.Emit(OpCodes.Ldstr, infos[i].Name); setGenerator.Emit(OpCodes.Ldc_I4_S, j++); setGenerator.Emit(OpCodes.Box, typeof(Int32)); setGenerator.Emit(OpCodes.Call, typeof(Hashtable).GetMethod("Add", new Type[] { typeof(object), typeof(object) })); } setGenerator.Emit(OpCodes.Volatile); setGenerator.Emit(OpCodes.Stsfld, setHashtableBuilder);setGenerator.MarkLabel(L_0220);
setGenerator.Emit(OpCodes.Ldarg_2); setGenerator.Emit(OpCodes.Dup); setGenerator.Emit(OpCodes.Stloc_0); setGenerator.Emit(OpCodes.Brfalse, L_053b); setGenerator.Emit(OpCodes.Volatile); setGenerator.Emit(OpCodes.Ldsfld, setHashtableBuilder); // [mscorlib]System.Collections.Hashtable <PrivateImplementationDetails>::$$method0x6000022-1 setGenerator.Emit(OpCodes.Ldloc_0); setGenerator.Emit(OpCodes.Call, typeof(Hashtable).GetMethod("get_Item", new Type[] { typeof(object) })); setGenerator.Emit(OpCodes.Dup); setGenerator.Emit(OpCodes.Stloc_0); setGenerator.Emit(OpCodes.Brfalse, L_053b); setGenerator.Emit(OpCodes.Ldloc_0); setGenerator.Emit(OpCodes.Unbox, typeof(Int32)); setGenerator.Emit(OpCodes.Ldind_I4); setGenerator.Emit(OpCodes.Switch, setLabels); setGenerator.Emit(OpCodes.Br, L_053b);for (int i = 0, j = 0; i < infos.Length; i++)
{ MethodInfo minfo = type.GetMethod("set_" + infos[i].Name); if (minfo == null || minfo.GetParameters().Length > 1) continue; setGenerator.MarkLabel(setLabels[j++]); setGenerator.Emit(OpCodes.Ldarg_1); setGenerator.Emit(OpCodes.Castclass, type); // NoReflection.TestClass setGenerator.Emit(OpCodes.Ldarg_3); if (infos[i].PropertyType.IsValueType) { setGenerator.Emit(OpCodes.Unbox, infos[i].PropertyType); if (infos[i].PropertyType == typeof(Int64)) setGenerator.Emit(OpCodes.Ldind_I8); if (infos[i].PropertyType == typeof(Int32)) setGenerator.Emit(OpCodes.Ldind_I4); if (infos[i].PropertyType == typeof(Int16)) setGenerator.Emit(OpCodes.Ldind_I2); if (infos[i].PropertyType == typeof(Byte)) setGenerator.Emit(OpCodes.Ldind_U1); if (infos[i].PropertyType == typeof(SByte)) setGenerator.Emit(OpCodes.Ldind_I1); if (infos[i].PropertyType == typeof(Boolean)) setGenerator.Emit(OpCodes.Ldind_I1); if (infos[i].PropertyType == typeof(UInt64)) setGenerator.Emit(OpCodes.Ldind_I8); if (infos[i].PropertyType == typeof(UInt32)) setGenerator.Emit(OpCodes.Ldind_U4); if (infos[i].PropertyType == typeof(UInt16)) setGenerator.Emit(OpCodes.Ldind_U2); if (infos[i].PropertyType == typeof(float)) setGenerator.Emit(OpCodes.Conv_R4); if (infos[i].PropertyType == typeof(Decimal)) setGenerator.Emit(OpCodes.Ldobj, typeof(Decimal)); if (infos[i].PropertyType == typeof(DateTime)) setGenerator.Emit(OpCodes.Ldobj, typeof(DateTime));}
else { setGenerator.Emit(OpCodes.Castclass, infos[i].PropertyType); // NoReflection.TestClass } setGenerator.Emit(OpCodes.Callvirt, minfo); setGenerator.Emit(OpCodes.Br, setRet);}
setGenerator.MarkLabel(L_053b);
if (type.BaseType == typeof(Array)) { setGenerator.Emit(OpCodes.Ldarg_2); setGenerator.Emit(OpCodes.Ldc_I4_0); setGenerator.Emit(OpCodes.Callvirt, typeof(string).GetMethod("get_Chars", new Type[] { typeof(Int32) })); setGenerator.Emit(OpCodes.Call, typeof(Char).GetMethod("IsDigit", new Type[] { typeof(Char) })); setGenerator.Emit(OpCodes.Brfalse_S, L_0568); setGenerator.Emit(OpCodes.Ldarg_1); setGenerator.Emit(OpCodes.Castclass, typeof(object[])); setGenerator.Emit(OpCodes.Ldarg_2); setGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) })); setGenerator.Emit(OpCodes.Ldarg_3); setGenerator.Emit(OpCodes.Stelem_Ref); setGenerator.MarkLabel(L_0568); setGenerator.Emit(OpCodes.Br, setRet); } else { PropertyInfo testInfo; testInfo = type.GetProperty("Item", new Type[] { typeof(Int32) }); if (testInfo != null) { MethodInfo intSetIndexer = type.GetMethod("set_Item", new Type[] { typeof(Int32), testInfo.PropertyType }); if (intSetIndexer != null && intSetIndexer.GetParameters()[0].ParameterType != typeof(object)) { setGenerator.Emit(OpCodes.Ldarg_2); setGenerator.Emit(OpCodes.Ldc_I4_0); setGenerator.Emit(OpCodes.Callvirt, typeof(string).GetMethod("get_Chars", new Type[] { typeof(Int32) })); setGenerator.Emit(OpCodes.Call, typeof(Char).GetMethod("IsDigit", new Type[] { typeof(Char) })); setGenerator.Emit(OpCodes.Brfalse_S, L_0568); setGenerator.Emit(OpCodes.Ldarg_1); setGenerator.Emit(OpCodes.Castclass, type); setGenerator.Emit(OpCodes.Ldarg_2); setGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(string) })); setGenerator.Emit(OpCodes.Ldarg_3); setGenerator.Emit(OpCodes.Castclass, typeof(string)); setGenerator.Emit(OpCodes.Callvirt, intSetIndexer); setGenerator.Emit(OpCodes.Br, setRet); setGenerator.MarkLabel(L_0568); } } testInfo = type.GetProperty("Item", new Type[] { typeof(String) }); if (testInfo != null) { MethodInfo strSetIndexer = type.GetMethod("set_Item", new Type[] { typeof(string), testInfo.PropertyType }); if (strSetIndexer != null) {setGenerator.Emit(OpCodes.Ldarg_1);
setGenerator.Emit(OpCodes.Castclass, type); setGenerator.Emit(OpCodes.Ldarg_2); setGenerator.Emit(OpCodes.Ldarg_3); if (testInfo.PropertyType.IsValueType) { setGenerator.Emit(OpCodes.Unbox, testInfo.PropertyType); if (testInfo.PropertyType == typeof(Int64)) setGenerator.Emit(OpCodes.Ldind_I8); if (testInfo.PropertyType == typeof(Int32)) setGenerator.Emit(OpCodes.Ldind_I4); if (testInfo.PropertyType == typeof(Int16)) setGenerator.Emit(OpCodes.Ldind_I2); if (testInfo.PropertyType == typeof(Byte)) setGenerator.Emit(OpCodes.Ldind_U1); if (testInfo.PropertyType == typeof(SByte)) setGenerator.Emit(OpCodes.Ldind_I1); if (testInfo.PropertyType == typeof(Boolean)) setGenerator.Emit(OpCodes.Ldind_I1); if (testInfo.PropertyType == typeof(UInt64)) setGenerator.Emit(OpCodes.Ldind_I8); if (testInfo.PropertyType == typeof(UInt32)) setGenerator.Emit(OpCodes.Ldind_U4); if (testInfo.PropertyType == typeof(UInt16)) setGenerator.Emit(OpCodes.Ldind_U2); if (testInfo.PropertyType == typeof(Decimal)) setGenerator.Emit(OpCodes.Ldobj, typeof(Decimal)); if (testInfo.PropertyType == typeof(DateTime)) setGenerator.Emit(OpCodes.Ldobj, typeof(DateTime)); } else { setGenerator.Emit(OpCodes.Castclass, testInfo.PropertyType); }setGenerator.Emit(OpCodes.Callvirt, strSetIndexer);
setGenerator.Emit(OpCodes.Br, setRet); setGenerator.MarkLabel(L_0593); } } } setGenerator.Emit(OpCodes.Ldstr, "The property named "); setGenerator.Emit(OpCodes.Ldarg_2); setGenerator.Emit(OpCodes.Ldstr, " does not exists"); setGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string), typeof(string) })); setGenerator.Emit(OpCodes.Newobj, typeof(Exception).GetConstructor(new Type[] { typeof(string) })); setGenerator.Emit(OpCodes.Throw); setGenerator.MarkLabel(setRet); setGenerator.Emit(OpCodes.Ret);#endregion
Type t = typeBuilder.CreateType(); //assyBuilder.Save("ValueHandler." + type.FullName + ".dll"); IValueHandler result = Activator.CreateInstance(t) as IValueHandler; handlers.Add(type, result); }转载地址:https://blog.csdn.net/gooer/article/details/2898023 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!