Advertisement
Guest User

Untitled

a guest
Mar 18th, 2018
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.89 KB | None | 0 0
  1. public class TypeEqualityComparer : IEqualityComparer<Type[]>{
  2. public bool Equals(Type[] x, Type[] y) {
  3. if (x.Length != y.Length) {
  4. return false;
  5. }
  6. for (int i = 0; i < x.Length; i++) {
  7. if (x[i] != y[i]) {
  8. return false;
  9. }
  10. }
  11. return true;
  12. }
  13.  
  14. public int GetHashCode(Type[] obj) {
  15. int result = 17;
  16. for (int i = 0; i < obj.Length; i++) {
  17. unchecked {
  18. result = result * 23 + obj[i].GetHashCode();
  19. }
  20. }
  21. return result;
  22. }
  23. }
  24.  
  25. public class Autoproxy {
  26.  
  27. static Autoproxy() {
  28. AssemblyName name = new AssemblyName("PBJBSDynamicAssembly");
  29. AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
  30. moduleBuilder = assemblyBuilder.DefineDynamicModule("PBJBSDynamicAssembly");
  31. proxies = new Dictionary<Type[], Type>(new TypeEqualityComparer());
  32. }
  33.  
  34. private static readonly ModuleBuilder moduleBuilder;
  35. private static readonly Dictionary<Type[], Type> proxies;
  36.  
  37. [MethodImpl(MethodImplOptions.Synchronized)]
  38. public static Autoproxy Proxify(object target, params Type[] proxyTypes) {
  39. if (!proxies.ContainsKey(proxyTypes)) {
  40. TypeBuilder tb = moduleBuilder.DefineType(MakeProxyName(target),
  41. TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, typeof(Autoproxy), proxyTypes);
  42.  
  43. CreateProxyType(tb, proxyTypes);
  44.  
  45. Type objectType = tb.CreateType();
  46. proxies[proxyTypes] = objectType;
  47. }
  48.  
  49. Type type = proxies[proxyTypes];
  50. return (Autoproxy) Activator.CreateInstance(type, new object[] { target });
  51. }
  52.  
  53. private static string MakeProxyName(object target) {
  54. if (target == null)
  55. return "Null$Proxy";
  56. return target.GetType().Name + "$Proxy";
  57. }
  58.  
  59. private static void CreateProxyType(TypeBuilder builder, Type[] types) {
  60. List<MethodInfo> methods = new List<MethodInfo> ();
  61.  
  62. foreach (Type type in types) {
  63. DiscoverProxyContents(type, methods);
  64. }
  65.  
  66. BuildProxyType(builder, methods);
  67. }
  68.  
  69. private static void BuildProxyType(TypeBuilder builder, List<MethodInfo> methods) {
  70. ConstructorBuilder cb = builder.DefineConstructor(MethodAttributes.Public, CallingConventions.Any, new Type[] { typeof(object) });
  71. ILGenerator generator = cb.GetILGenerator();
  72. generator.Emit(OpCodes.Ldarg_0);
  73. generator.Emit(OpCodes.Ldarg_1);
  74. generator.Emit(OpCodes.Call, typeof(Autoproxy).GetConstructor(new Type[]{ typeof(object) }));
  75. generator.Emit(OpCodes.Ret);
  76.  
  77. foreach (MethodInfo method in methods) {
  78. BuildProxyMethod(builder, method);
  79. }
  80. }
  81.  
  82. private static void BuildProxyMethod(TypeBuilder builder, MethodInfo method) {
  83. MethodBuilder mb = builder.DefineMethod(method.Name, MethodAttributes.Public | MethodAttributes.Final);
  84.  
  85. ParameterInfo[] parameters = method.GetParameters();
  86. Type[] pt = new Type[parameters.Length];
  87. for (int i=0; i<parameters.Length; i++) {
  88. pt[i] = parameters[i].ParameterType;
  89. }
  90. mb.SetParameters(pt);
  91. for (int i=0; i<parameters.Length; i++) {
  92. mb.DefineParameter(i, parameters[i].Attributes, parameters[i].Name);
  93. }
  94.  
  95. mb.SetReturnType(method.ReturnType);
  96.  
  97. ILGenerator generator = mb.GetILGenerator();
  98.  
  99. generator.Emit(OpCodes.Ldarg_0);
  100. generator.Emit(OpCodes.Ldfld, typeof(Autoproxy).GetField("proxy", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
  101. for (int i=0; i<parameters.Length; i++) {
  102. generator.Emit(OpCodes.Ldarg, i+1);
  103. }
  104. generator.Emit(OpCodes.Callvirt, method);
  105.  
  106. if (method.ReturnType == typeof(void)) {
  107. generator.Emit(OpCodes.Pop);
  108. }
  109.  
  110. generator.Emit(OpCodes.Ret);
  111. }
  112.  
  113. private static void DiscoverProxyContents(Type type, List<MethodInfo> methods) {
  114. foreach (MethodInfo method in type.GetMethods()) {
  115. if (PublicMethod(method) && MethodNotInList(methods, method)) {
  116. methods.Add(method);
  117. }
  118. }
  119. }
  120.  
  121. private static bool PublicMethod(MethodInfo method) {
  122. return method.IsPublic && !method.IsStatic;
  123. }
  124.  
  125. private static bool MethodNotInList(List<MethodInfo> methods, MethodInfo method) {
  126. foreach (MethodInfo m in methods) {
  127. if (m == method)
  128. return false;
  129. if (m != method) {
  130. if (m.Name == method.Name) {
  131. if (m.ReturnType != method.ReturnType) {
  132. return false;
  133. }
  134. ParameterInfo[] mParams = m.GetParameters();
  135. ParameterInfo[] methodParams = method.GetParameters();
  136.  
  137. if (mParams.Length == methodParams.Length) {
  138. for (int i=0; i<mParams.Length; i++) {
  139. Type mType = mParams[i].ParameterType;
  140. Type methodType = methodParams[i].ParameterType;
  141. if (mType != methodType) {
  142. goto OUTER;
  143. }
  144. }
  145. return false;
  146. }
  147. }
  148. }
  149. OUTER:
  150. ;
  151. }
  152. return true;
  153. }
  154.  
  155. protected readonly object proxy;
  156.  
  157. public object Proxy { get {
  158. return proxy;
  159. }
  160. }
  161.  
  162. public Autoproxy(object proxy) {
  163. this.proxy = proxy;
  164. }
  165.  
  166. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement