public static void Clone(Hashtable dicc) { Assembly asmSource = Assembly.LoadFrom("...nombre del ensamblado original..."); AssemblyName asmName = new AssemblyName("...nuevo nombre de ensamblado..."); AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Save); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Utilidades.dll", "Utilidades.dll"); //Copiar los tipos foreach (Type t in asmSource.GetTypes()) { string newTypeName = dicc[t.Name] == null ? t.FullName : t.Namespace + "." + (string)dicc[t.Name]; TypeBuilder typeBuilder = moduleBuilder.DefineType(newTypeName, t.Attributes, t.BaseType, t.GetInterfaces()); //Copiar los miembros de cada tipo foreach (MemberInfo mInfo in t.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.CreateInstance| BindingFlags.Instance| BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)) { //Copiar las variables if (mInfo is FieldInfo) { FieldInfo f = (FieldInfo) mInfo; string newFieldName = dicc[f.Name] == null ? f.Name : (string)dicc[f.Name]; typeBuilder.DefineField(newFieldName, f.FieldType, f.Attributes); } //Copiar los constructores else if (mInfo is ConstructorInfo) { ConstructorInfo cInfo = (ConstructorInfo) mInfo; ConstructorBuilder cBuilder = typeBuilder.DefineConstructor(cInfo.Attributes, cInfo.CallingConvention, ParameterType(cInfo.GetParameters())); ILGenerator iLGen = cBuilder.GetILGenerator(); iLGen.Emit(OpCodes.Ldarg_0); iLGen.Emit(OpCodes.Call, typeof(object).GetConstructor(new Type[]{})); iLGen.Emit(OpCodes.Ret); } //Copiar los métodos else if (mInfo is MethodInfo) { MethodInfo m = (MethodInfo) mInfo; string newMethodName = dicc[m.Name] == null ? m.Name : (string)dicc[m.Name]; MethodBuilder mBuilder = typeBuilder.DefineMethod( newMethodName, m.Attributes, m.CallingConvention, m.ReturnType, ParameterType(m.GetParameters())); MethodBody mBody = m.GetMethodBody(); byte[] ILByteArray = mBody.GetILAsByteArray(); //Emitir el mismo array de bytes mBuilder.CreateMethodBody(ILByteArray, ILByteArray.Length); } else ... } typeBuilder.CreateType(); //Concluye la emisión de un tipo } moduleBuilder.CreateGlobalFunctions(); //Concluye la emisión del módulo assemblyBuilder.Save("Utilidades.dll"); } private static Type[] ParameterType(ParameterInfo[] pInfo) { Type[] t = new Type[pInfo.Length]; for (int i = 0; i < pInfo.Length; i++) t[i] = pInfo[i].ParameterType; return t; } Fuente 2. |