mirror of
				https://github.com/esiur/esiur-dotnet.git
				synced 2025-10-30 23:51:34 +00:00 
			
		
		
		
	.Net 6 Upgrade
This commit is contained in:
		| @@ -7,72 +7,71 @@ using System.Reflection; | ||||
| using System.Reflection.Emit; | ||||
| using System.Text; | ||||
|  | ||||
| namespace Esiur.Proxy | ||||
| namespace Esiur.Proxy; | ||||
| public static class ResourceProxy | ||||
| { | ||||
|     public static class ResourceProxy | ||||
|     { | ||||
|         static Dictionary<Type, Type> cache = new Dictionary<Type, Type>(); | ||||
|          | ||||
|     static Dictionary<Type, Type> cache = new Dictionary<Type, Type>(); | ||||
|  | ||||
| #if NETSTANDARD | ||||
|         static MethodInfo modifyMethod = typeof(Instance).GetTypeInfo().GetMethod("Modified"); | ||||
|         static MethodInfo instanceGet = typeof(IResource).GetTypeInfo().GetProperty("Instance").GetGetMethod(); | ||||
|     static MethodInfo modifyMethod = typeof(Instance).GetTypeInfo().GetMethod("Modified"); | ||||
|     static MethodInfo instanceGet = typeof(IResource).GetTypeInfo().GetProperty("Instance").GetGetMethod(); | ||||
| #else | ||||
|         static MethodInfo modifyMethod = typeof(Instance).GetMethod("Modified"); | ||||
|         static MethodInfo instanceGet = typeof(IResource).GetProperty("Instance").GetGetMethod(); | ||||
| #endif | ||||
|  | ||||
|  | ||||
|         public static Type GetBaseType(object resource) | ||||
|     public static Type GetBaseType(object resource) | ||||
|     { | ||||
|         return GetBaseType(resource.GetType()); | ||||
|     } | ||||
|  | ||||
|     public static Type GetBaseType(Type type) | ||||
|     { | ||||
|         if (type.Assembly.IsDynamic) | ||||
|             return type.GetTypeInfo().BaseType; | ||||
|         else | ||||
|             return type; | ||||
|  | ||||
|         //            if (type.FullName.Contains("Esiur.Proxy.T")) | ||||
|         //#if NETSTANDARD | ||||
|         //                return type.GetTypeInfo().BaseType; | ||||
|         //#else | ||||
|         //            return type.BaseType; | ||||
|         //#endif | ||||
|         //            else | ||||
|         //                return type; | ||||
|     } | ||||
|  | ||||
|     public static Type GetProxy(Type type) | ||||
|     { | ||||
|  | ||||
|         if (cache.ContainsKey(type)) | ||||
|             return cache[type]; | ||||
|  | ||||
|         // check if the type was made with code generation | ||||
|         if (type.GetCustomAttribute<ResourceAttribute>(false) != null) | ||||
|         { | ||||
|             return GetBaseType(resource.GetType()); | ||||
|             cache.Add(type, type); | ||||
|             return type; | ||||
|         } | ||||
|  | ||||
|         public static Type GetBaseType(Type type) | ||||
|         if (!Codec.ImplementsInterface(type, typeof(IResource))) | ||||
|         { | ||||
|             if (type.Assembly.IsDynamic) | ||||
|                 return type.GetTypeInfo().BaseType; | ||||
|             else | ||||
|                 return type; | ||||
|  | ||||
| //            if (type.FullName.Contains("Esiur.Proxy.T")) | ||||
| //#if NETSTANDARD | ||||
| //                return type.GetTypeInfo().BaseType; | ||||
| //#else | ||||
| //            return type.BaseType; | ||||
| //#endif | ||||
| //            else | ||||
| //                return type; | ||||
|             cache.Add(type, type); | ||||
|             return type; | ||||
|         } | ||||
|  | ||||
|         public static Type GetProxy(Type type) | ||||
|         { | ||||
|  | ||||
|             if (cache.ContainsKey(type)) | ||||
|                 return cache[type]; | ||||
|  | ||||
|             // check if the type was made with code generation | ||||
|             if (type.GetCustomAttribute<ResourceAttribute>(false) != null) | ||||
|             { | ||||
|                 cache.Add(type, type); | ||||
|                 return type; | ||||
|             } | ||||
|  | ||||
|             if (!Codec.ImplementsInterface(type, typeof(IResource))) | ||||
|             { | ||||
|                 cache.Add(type, type); | ||||
|                 return type; | ||||
|             } | ||||
|  | ||||
| #if NETSTANDARD | ||||
|             var typeInfo = type.GetTypeInfo(); | ||||
|         var typeInfo = type.GetTypeInfo(); | ||||
|  | ||||
|             if (typeInfo.IsSealed || typeInfo.IsAbstract) | ||||
|                 throw new Exception("Sealed/Abastract classes can't be proxied."); | ||||
|         if (typeInfo.IsSealed || typeInfo.IsAbstract) | ||||
|             throw new Exception("Sealed/Abastract classes can't be proxied."); | ||||
|  | ||||
|             var props = from p in typeInfo.GetProperties(BindingFlags.Instance | BindingFlags.Public) | ||||
|                         where p.CanWrite && p.SetMethod.IsVirtual && !p.SetMethod.IsFinal &&  | ||||
|                         p.GetCustomAttribute<PublicAttribute>(false) != null | ||||
|                         select p; | ||||
|         var props = from p in typeInfo.GetProperties(BindingFlags.Instance | BindingFlags.Public) | ||||
|                     where p.CanWrite && p.SetMethod.IsVirtual && !p.SetMethod.IsFinal && | ||||
|                     p.GetCustomAttribute<PublicAttribute>(false) != null | ||||
|                     select p; | ||||
|  | ||||
| #else | ||||
|             if (type.IsSealed) | ||||
| @@ -84,172 +83,171 @@ namespace Esiur.Proxy | ||||
|                 select p; | ||||
|  | ||||
| #endif | ||||
|             var assemblyName = new AssemblyName("Esiur.Proxy.T." + type.Assembly.GetName().Name);// type.Namespace); | ||||
|             assemblyName.Version = type.Assembly.GetName().Version; | ||||
|             assemblyName.CultureInfo = type.Assembly.GetName().CultureInfo; | ||||
|             //assemblyName.SetPublicKeyToken(null); | ||||
|         var assemblyName = new AssemblyName("Esiur.Proxy.T." + type.Assembly.GetName().Name);// type.Namespace); | ||||
|         assemblyName.Version = type.Assembly.GetName().Version; | ||||
|         assemblyName.CultureInfo = type.Assembly.GetName().CultureInfo; | ||||
|         //assemblyName.SetPublicKeyToken(null); | ||||
|  | ||||
|             var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); | ||||
|             var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name); | ||||
|             var typeName = "Esiur.Proxy.T." + type.FullName;// Assembly.CreateQualifiedName(assemblyName.FullName, "Esiur.Proxy.T." + type.FullName); | ||||
|         var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); | ||||
|         var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name); | ||||
|         var typeName = "Esiur.Proxy.T." + type.FullName;// Assembly.CreateQualifiedName(assemblyName.FullName, "Esiur.Proxy.T." + type.FullName); | ||||
|  | ||||
|             var typeBuilder = moduleBuilder.DefineType(typeName, | ||||
|                 TypeAttributes.Public | TypeAttributes.Class, type); | ||||
|         var typeBuilder = moduleBuilder.DefineType(typeName, | ||||
|             TypeAttributes.Public | TypeAttributes.Class, type); | ||||
|  | ||||
|             foreach (PropertyInfo propertyInfo in props) | ||||
|                 CreateProperty(propertyInfo, typeBuilder, type); | ||||
|         foreach (PropertyInfo propertyInfo in props) | ||||
|             CreateProperty(propertyInfo, typeBuilder, type); | ||||
|  | ||||
|  | ||||
|  | ||||
| #if NETSTANDARD | ||||
|             var t = typeBuilder.CreateTypeInfo().AsType(); | ||||
|             cache.Add(type, t); | ||||
|             return t; | ||||
|         var t = typeBuilder.CreateTypeInfo().AsType(); | ||||
|         cache.Add(type, t); | ||||
|         return t; | ||||
| #else | ||||
|              | ||||
|             var t = typeBuilder.CreateType(); | ||||
|             cache.Add(type, t); | ||||
|             return t; | ||||
| #endif | ||||
|         } | ||||
|  | ||||
|         public static Type GetProxy<T>() | ||||
|             where T : IResource | ||||
|         { | ||||
|             return GetProxy(typeof(T)); | ||||
|         } | ||||
|  | ||||
|  | ||||
|  | ||||
|         //private static void C | ||||
|         private static void CreateProperty(PropertyInfo pi, TypeBuilder typeBuilder, Type resourceType) | ||||
|         { | ||||
|             var propertyBuilder = typeBuilder.DefineProperty(pi.Name, PropertyAttributes.None, pi.PropertyType, null); | ||||
|  | ||||
|             // Create set method | ||||
|             MethodBuilder builder = typeBuilder.DefineMethod("set_" + pi.Name, | ||||
|                 MethodAttributes.Public | MethodAttributes.Virtual, null, new Type[] { pi.PropertyType }); | ||||
|             builder.DefineParameter(1, ParameterAttributes.None, "value"); | ||||
|             ILGenerator g = builder.GetILGenerator(); | ||||
|  | ||||
|             var getInstance = resourceType.GetTypeInfo().GetProperty("Instance").GetGetMethod(); | ||||
|  | ||||
|  | ||||
|             //g.Emit(OpCodes.Ldarg_0); | ||||
|             //g.Emit(OpCodes.Ldarg_1); | ||||
|             //g.Emit(OpCodes.Call, pi.GetSetMethod()); | ||||
|             //g.Emit(OpCodes.Nop); | ||||
|  | ||||
|             //g.Emit(OpCodes.Ldarg_0); | ||||
|             //g.Emit(OpCodes.Call, getInstance); | ||||
|             //g.Emit(OpCodes.Ldstr, pi.Name); | ||||
|             //g.Emit(OpCodes.Call, modifyMethod); | ||||
|             //g.Emit(OpCodes.Nop); | ||||
|  | ||||
|             //g.Emit(OpCodes.Ret); | ||||
|  | ||||
|             Label exitMethod = g.DefineLabel(); | ||||
|             Label callModified = g.DefineLabel(); | ||||
|  | ||||
|             g.Emit(OpCodes.Nop); | ||||
|  | ||||
|             g.Emit(OpCodes.Ldarg_0); | ||||
|             g.Emit(OpCodes.Ldarg_1); | ||||
|             g.Emit(OpCodes.Call, pi.GetSetMethod()); | ||||
|             g.Emit(OpCodes.Nop); | ||||
|  | ||||
|             g.Emit(OpCodes.Ldarg_0); | ||||
|             g.Emit(OpCodes.Call, getInstance); | ||||
|             g.Emit(OpCodes.Dup); | ||||
|  | ||||
|             g.Emit(OpCodes.Brtrue_S, callModified); | ||||
|  | ||||
|             g.Emit(OpCodes.Pop); | ||||
|             g.Emit(OpCodes.Br_S, exitMethod); | ||||
|  | ||||
|             g.MarkLabel(callModified); | ||||
|  | ||||
|             g.Emit(OpCodes.Ldstr, pi.Name); | ||||
|             g.Emit(OpCodes.Call, modifyMethod); | ||||
|             g.Emit(OpCodes.Nop); | ||||
|  | ||||
|             g.MarkLabel(exitMethod); | ||||
|             g.Emit(OpCodes.Ret); | ||||
|             propertyBuilder.SetSetMethod(builder); | ||||
|  | ||||
|  | ||||
|             builder = typeBuilder.DefineMethod("get_" + pi.Name, MethodAttributes.Public | MethodAttributes.Virtual, pi.PropertyType, null); | ||||
|             g = builder.GetILGenerator(); | ||||
|             g.Emit(OpCodes.Ldarg_0); | ||||
|             g.Emit(OpCodes.Call, pi.GetGetMethod()); | ||||
|             g.Emit(OpCodes.Ret); | ||||
|  | ||||
|             propertyBuilder.SetGetMethod(builder); | ||||
|  | ||||
|             // g.Emit(OpCodes.Ldarg_0); | ||||
|             // g.Emit(OpCodes.Call, pi.GetGetMethod()); | ||||
|             // g.Emit(OpCodes.Ret); | ||||
|  | ||||
|             // propertyBuilder.SetGetMethod(builder); | ||||
|  | ||||
|  | ||||
|             /* | ||||
|             Label callModified = g.DefineLabel(); | ||||
|             Label exitMethod = g.DefineLabel(); | ||||
|  | ||||
|              | ||||
|              //   IL_0000: ldarg.0 | ||||
| 	            //IL_0001: call instance class [Esiur]Esiur.Resource.Instance [Esiur]Esiur.Resource.Resource::get_Instance() | ||||
| 	            //// (no C# code) | ||||
| 	            //IL_0006: dup | ||||
| 	            //IL_0007: brtrue.s IL_000c | ||||
| 	            //IL_0009: pop | ||||
| 	            //// } | ||||
| 	            //IL_000a: br.s IL_0017 | ||||
| 	            //// (no C# code) | ||||
| 	            //IL_000c: ldstr "Level3" | ||||
| 	            //IL_0011: call instance void [Esiur]Esiur.Resource.Instance::Modified(string) | ||||
| 	            //IL_0016: nop | ||||
| 	            //IL_0017: ret | ||||
|               | ||||
|  | ||||
|             // Add IL code for set method | ||||
|             g.Emit(OpCodes.Nop); | ||||
|             g.Emit(OpCodes.Ldarg_0); | ||||
|             g.Emit(OpCodes.Ldarg_1); | ||||
|             g.Emit(OpCodes.Call, pi.GetSetMethod()); | ||||
|  | ||||
|              | ||||
|              //   IL_0000: ldarg.0 | ||||
|  	           // IL_0001: call instance class [Esiur]Esiur.Resource.Instance [Esiur]Esiur.Resource.Resource::get_Instance() | ||||
|  	           // IL_0006: ldstr "Level3" | ||||
| 	            //IL_000b: callvirt instance void [Esiur]Esiur.Resource.Instance::Modified(string) | ||||
| 	            //IL_0010: ret | ||||
|               | ||||
|  | ||||
|             // Call property changed for object | ||||
|             g.Emit(OpCodes.Nop); | ||||
|             g.Emit(OpCodes.Ldarg_0); | ||||
|             g.Emit(OpCodes.Call, instanceGet); | ||||
|  | ||||
|             g.Emit(OpCodes.Dup); | ||||
|             g.Emit(OpCodes.Brtrue_S, callModified); | ||||
|             g.Emit(OpCodes.Pop); | ||||
|             g.Emit(OpCodes.Br_S, exitMethod); | ||||
|  | ||||
|             g.MarkLabel(callModified); | ||||
|             g.Emit(OpCodes.Ldstr, pi.Name); | ||||
|             g.Emit(OpCodes.Callvirt, modifyMethod); | ||||
|             g.Emit(OpCodes.Nop); | ||||
|             g.MarkLabel(exitMethod); | ||||
|             g.Emit(OpCodes.Ret); | ||||
|             propertyBuilder.SetSetMethod(builder); | ||||
|  | ||||
|  | ||||
|             // create get method | ||||
|  | ||||
|             */ | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public static Type GetProxy<T>() | ||||
|         where T : IResource | ||||
|     { | ||||
|         return GetProxy(typeof(T)); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     //private static void C | ||||
|     private static void CreateProperty(PropertyInfo pi, TypeBuilder typeBuilder, Type resourceType) | ||||
|     { | ||||
|         var propertyBuilder = typeBuilder.DefineProperty(pi.Name, PropertyAttributes.None, pi.PropertyType, null); | ||||
|  | ||||
|         // Create set method | ||||
|         MethodBuilder builder = typeBuilder.DefineMethod("set_" + pi.Name, | ||||
|             MethodAttributes.Public | MethodAttributes.Virtual, null, new Type[] { pi.PropertyType }); | ||||
|         builder.DefineParameter(1, ParameterAttributes.None, "value"); | ||||
|         ILGenerator g = builder.GetILGenerator(); | ||||
|  | ||||
|         var getInstance = resourceType.GetTypeInfo().GetProperty("Instance").GetGetMethod(); | ||||
|  | ||||
|  | ||||
|         //g.Emit(OpCodes.Ldarg_0); | ||||
|         //g.Emit(OpCodes.Ldarg_1); | ||||
|         //g.Emit(OpCodes.Call, pi.GetSetMethod()); | ||||
|         //g.Emit(OpCodes.Nop); | ||||
|  | ||||
|         //g.Emit(OpCodes.Ldarg_0); | ||||
|         //g.Emit(OpCodes.Call, getInstance); | ||||
|         //g.Emit(OpCodes.Ldstr, pi.Name); | ||||
|         //g.Emit(OpCodes.Call, modifyMethod); | ||||
|         //g.Emit(OpCodes.Nop); | ||||
|  | ||||
|         //g.Emit(OpCodes.Ret); | ||||
|  | ||||
|         Label exitMethod = g.DefineLabel(); | ||||
|         Label callModified = g.DefineLabel(); | ||||
|  | ||||
|         g.Emit(OpCodes.Nop); | ||||
|  | ||||
|         g.Emit(OpCodes.Ldarg_0); | ||||
|         g.Emit(OpCodes.Ldarg_1); | ||||
|         g.Emit(OpCodes.Call, pi.GetSetMethod()); | ||||
|         g.Emit(OpCodes.Nop); | ||||
|  | ||||
|         g.Emit(OpCodes.Ldarg_0); | ||||
|         g.Emit(OpCodes.Call, getInstance); | ||||
|         g.Emit(OpCodes.Dup); | ||||
|  | ||||
|         g.Emit(OpCodes.Brtrue_S, callModified); | ||||
|  | ||||
|         g.Emit(OpCodes.Pop); | ||||
|         g.Emit(OpCodes.Br_S, exitMethod); | ||||
|  | ||||
|         g.MarkLabel(callModified); | ||||
|  | ||||
|         g.Emit(OpCodes.Ldstr, pi.Name); | ||||
|         g.Emit(OpCodes.Call, modifyMethod); | ||||
|         g.Emit(OpCodes.Nop); | ||||
|  | ||||
|         g.MarkLabel(exitMethod); | ||||
|         g.Emit(OpCodes.Ret); | ||||
|         propertyBuilder.SetSetMethod(builder); | ||||
|  | ||||
|  | ||||
|         builder = typeBuilder.DefineMethod("get_" + pi.Name, MethodAttributes.Public | MethodAttributes.Virtual, pi.PropertyType, null); | ||||
|         g = builder.GetILGenerator(); | ||||
|         g.Emit(OpCodes.Ldarg_0); | ||||
|         g.Emit(OpCodes.Call, pi.GetGetMethod()); | ||||
|         g.Emit(OpCodes.Ret); | ||||
|  | ||||
|         propertyBuilder.SetGetMethod(builder); | ||||
|  | ||||
|         // g.Emit(OpCodes.Ldarg_0); | ||||
|         // g.Emit(OpCodes.Call, pi.GetGetMethod()); | ||||
|         // g.Emit(OpCodes.Ret); | ||||
|  | ||||
|         // propertyBuilder.SetGetMethod(builder); | ||||
|  | ||||
|  | ||||
|         /* | ||||
|         Label callModified = g.DefineLabel(); | ||||
|         Label exitMethod = g.DefineLabel(); | ||||
|  | ||||
|  | ||||
|          //   IL_0000: ldarg.0 | ||||
|             //IL_0001: call instance class [Esiur]Esiur.Resource.Instance [Esiur]Esiur.Resource.Resource::get_Instance() | ||||
|             //// (no C# code) | ||||
|             //IL_0006: dup | ||||
|             //IL_0007: brtrue.s IL_000c | ||||
|             //IL_0009: pop | ||||
|             //// } | ||||
|             //IL_000a: br.s IL_0017 | ||||
|             //// (no C# code) | ||||
|             //IL_000c: ldstr "Level3" | ||||
|             //IL_0011: call instance void [Esiur]Esiur.Resource.Instance::Modified(string) | ||||
|             //IL_0016: nop | ||||
|             //IL_0017: ret | ||||
|  | ||||
|  | ||||
|         // Add IL code for set method | ||||
|         g.Emit(OpCodes.Nop); | ||||
|         g.Emit(OpCodes.Ldarg_0); | ||||
|         g.Emit(OpCodes.Ldarg_1); | ||||
|         g.Emit(OpCodes.Call, pi.GetSetMethod()); | ||||
|  | ||||
|  | ||||
|          //   IL_0000: ldarg.0 | ||||
|            // IL_0001: call instance class [Esiur]Esiur.Resource.Instance [Esiur]Esiur.Resource.Resource::get_Instance() | ||||
|            // IL_0006: ldstr "Level3" | ||||
|             //IL_000b: callvirt instance void [Esiur]Esiur.Resource.Instance::Modified(string) | ||||
|             //IL_0010: ret | ||||
|  | ||||
|  | ||||
|         // Call property changed for object | ||||
|         g.Emit(OpCodes.Nop); | ||||
|         g.Emit(OpCodes.Ldarg_0); | ||||
|         g.Emit(OpCodes.Call, instanceGet); | ||||
|  | ||||
|         g.Emit(OpCodes.Dup); | ||||
|         g.Emit(OpCodes.Brtrue_S, callModified); | ||||
|         g.Emit(OpCodes.Pop); | ||||
|         g.Emit(OpCodes.Br_S, exitMethod); | ||||
|  | ||||
|         g.MarkLabel(callModified); | ||||
|         g.Emit(OpCodes.Ldstr, pi.Name); | ||||
|         g.Emit(OpCodes.Callvirt, modifyMethod); | ||||
|         g.Emit(OpCodes.Nop); | ||||
|         g.MarkLabel(exitMethod); | ||||
|         g.Emit(OpCodes.Ret); | ||||
|         propertyBuilder.SetSetMethod(builder); | ||||
|  | ||||
|  | ||||
|         // create get method | ||||
|  | ||||
|         */ | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user