DelegateTypeFactory.cs 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. using System;
  2. using System.Reflection;
  3. using System.Reflection.Emit;
  4. namespace Harmony
  5. {
  6. public class DelegateTypeFactory
  7. {
  8. readonly ModuleBuilder module;
  9. static int counter;
  10. public DelegateTypeFactory()
  11. {
  12. counter++;
  13. var name = new AssemblyName("HarmonyDTFAssembly" + counter);
  14. var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
  15. module = assembly.DefineDynamicModule("HarmonyDTFModule" + counter);
  16. }
  17. public Type CreateDelegateType(MethodInfo method)
  18. {
  19. var attr = TypeAttributes.Sealed | TypeAttributes.Public;
  20. var typeBuilder = module.DefineType("HarmonyDTFType" + counter, attr, typeof(MulticastDelegate));
  21. var constructor = typeBuilder.DefineConstructor(
  22. MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public,
  23. CallingConventions.Standard, new[] { typeof(object), typeof(IntPtr) });
  24. constructor.SetImplementationFlags(MethodImplAttributes.CodeTypeMask);
  25. var parameters = method.GetParameters();
  26. var invokeMethod = typeBuilder.DefineMethod(
  27. "Invoke", MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Public,
  28. method.ReturnType, parameters.Types());
  29. invokeMethod.SetImplementationFlags(MethodImplAttributes.CodeTypeMask);
  30. for (var i = 0; i < parameters.Length; i++)
  31. invokeMethod.DefineParameter(i + 1, ParameterAttributes.None, parameters[i].Name);
  32. return typeBuilder.CreateType();
  33. }
  34. }
  35. }