Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class TypeEqualityComparer : IEqualityComparer<Type[]>{
- public bool Equals(Type[] x, Type[] y) {
- if (x.Length != y.Length) {
- return false;
- }
- for (int i = 0; i < x.Length; i++) {
- if (x[i] != y[i]) {
- return false;
- }
- }
- return true;
- }
- public int GetHashCode(Type[] obj) {
- int result = 17;
- for (int i = 0; i < obj.Length; i++) {
- unchecked {
- result = result * 23 + obj[i].GetHashCode();
- }
- }
- return result;
- }
- }
- public class Autoproxy {
- static Autoproxy() {
- AssemblyName name = new AssemblyName("PBJBSDynamicAssembly");
- AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
- moduleBuilder = assemblyBuilder.DefineDynamicModule("PBJBSDynamicAssembly");
- proxies = new Dictionary<Type[], Type>(new TypeEqualityComparer());
- }
- private static readonly ModuleBuilder moduleBuilder;
- private static readonly Dictionary<Type[], Type> proxies;
- [MethodImpl(MethodImplOptions.Synchronized)]
- public static Autoproxy Proxify(object target, params Type[] proxyTypes) {
- if (!proxies.ContainsKey(proxyTypes)) {
- TypeBuilder tb = moduleBuilder.DefineType(MakeProxyName(target),
- TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, typeof(Autoproxy), proxyTypes);
- CreateProxyType(tb, proxyTypes);
- Type objectType = tb.CreateType();
- proxies[proxyTypes] = objectType;
- }
- Type type = proxies[proxyTypes];
- return (Autoproxy) Activator.CreateInstance(type, new object[] { target });
- }
- private static string MakeProxyName(object target) {
- if (target == null)
- return "Null$Proxy";
- return target.GetType().Name + "$Proxy";
- }
- private static void CreateProxyType(TypeBuilder builder, Type[] types) {
- List<MethodInfo> methods = new List<MethodInfo> ();
- foreach (Type type in types) {
- DiscoverProxyContents(type, methods);
- }
- BuildProxyType(builder, methods);
- }
- private static void BuildProxyType(TypeBuilder builder, List<MethodInfo> methods) {
- ConstructorBuilder cb = builder.DefineConstructor(MethodAttributes.Public, CallingConventions.Any, new Type[] { typeof(object) });
- ILGenerator generator = cb.GetILGenerator();
- generator.Emit(OpCodes.Ldarg_0);
- generator.Emit(OpCodes.Ldarg_1);
- generator.Emit(OpCodes.Call, typeof(Autoproxy).GetConstructor(new Type[]{ typeof(object) }));
- generator.Emit(OpCodes.Ret);
- foreach (MethodInfo method in methods) {
- BuildProxyMethod(builder, method);
- }
- }
- private static void BuildProxyMethod(TypeBuilder builder, MethodInfo method) {
- MethodBuilder mb = builder.DefineMethod(method.Name, MethodAttributes.Public | MethodAttributes.Final);
- ParameterInfo[] parameters = method.GetParameters();
- Type[] pt = new Type[parameters.Length];
- for (int i=0; i<parameters.Length; i++) {
- pt[i] = parameters[i].ParameterType;
- }
- mb.SetParameters(pt);
- for (int i=0; i<parameters.Length; i++) {
- mb.DefineParameter(i, parameters[i].Attributes, parameters[i].Name);
- }
- mb.SetReturnType(method.ReturnType);
- ILGenerator generator = mb.GetILGenerator();
- generator.Emit(OpCodes.Ldarg_0);
- generator.Emit(OpCodes.Ldfld, typeof(Autoproxy).GetField("proxy", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
- for (int i=0; i<parameters.Length; i++) {
- generator.Emit(OpCodes.Ldarg, i+1);
- }
- generator.Emit(OpCodes.Callvirt, method);
- if (method.ReturnType == typeof(void)) {
- generator.Emit(OpCodes.Pop);
- }
- generator.Emit(OpCodes.Ret);
- }
- private static void DiscoverProxyContents(Type type, List<MethodInfo> methods) {
- foreach (MethodInfo method in type.GetMethods()) {
- if (PublicMethod(method) && MethodNotInList(methods, method)) {
- methods.Add(method);
- }
- }
- }
- private static bool PublicMethod(MethodInfo method) {
- return method.IsPublic && !method.IsStatic;
- }
- private static bool MethodNotInList(List<MethodInfo> methods, MethodInfo method) {
- foreach (MethodInfo m in methods) {
- if (m == method)
- return false;
- if (m != method) {
- if (m.Name == method.Name) {
- if (m.ReturnType != method.ReturnType) {
- return false;
- }
- ParameterInfo[] mParams = m.GetParameters();
- ParameterInfo[] methodParams = method.GetParameters();
- if (mParams.Length == methodParams.Length) {
- for (int i=0; i<mParams.Length; i++) {
- Type mType = mParams[i].ParameterType;
- Type methodType = methodParams[i].ParameterType;
- if (mType != methodType) {
- goto OUTER;
- }
- }
- return false;
- }
- }
- }
- OUTER:
- ;
- }
- return true;
- }
- protected readonly object proxy;
- public object Proxy { get {
- return proxy;
- }
- }
- public Autoproxy(object proxy) {
- this.proxy = proxy;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement