| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Reflection;
- using System.Reflection.Emit;
-
- namespace EmitCreateDynamicProxy
- {
- class Program
- {
- static void Main(string[] args)
- {
- //var command = Proxy.Of<Command>();
- //command.Execute();
-
- //Console.WriteLine("Hi, Dennis, great, we got the interceptor works.");
- //Console.ReadLine();
-
- Model m = DynamicProxyGenerator.CreateDynamicProxy<Model>(true);
- var pc = m as INotifyPropertyChanged;
- pc.PropertyChanged += Pc_PropertyChanged;
- m.Name = "ddd";
- var d = new DDD();
- //d.PropertyChanged += Pc_PropertyChanged;
- d.Name = "nnn";
- //var x = new M();
- //x.Name = "000";
- Console.WriteLine("........");
- Console.ReadKey();
- }
-
- private static void Pc_PropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- Console.WriteLine($"PropertyChanged {e.PropertyName}");
- }
- }
-
- public class Command
- {
- public virtual void Execute()
- {
- Console.WriteLine("Command executing...");
- Console.WriteLine("Hello Kitty!");
- Console.WriteLine("Command executed.");
- }
- }
-
- public class Interceptor
- {
- public object Invoke(object @object, string @method, object[] parameters)
- {
- Console.WriteLine(
- string.Format("Interceptor does something before invoke [{0}]...", @method));
-
- var retObj = @object.GetType().GetMethod(@method).Invoke(@object, parameters);
-
- Console.WriteLine(
- string.Format("Interceptor does something after invoke [{0}]...", @method));
-
- return retObj;
- }
- }
-
- public class Proxy
- {
- public static T Of<T>() where T : class, new()
- {
- string nameOfAssembly = typeof(T).Name + "ProxyAssembly";
- string nameOfModule = typeof(T).Name + "ProxyModule";
- string nameOfType = typeof(T).Name + "Proxy";
-
- var assemblyName = new AssemblyName(nameOfAssembly);
- var assembly = AppDomain.CurrentDomain
- .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
- var moduleBuilder = assembly.DefineDynamicModule(nameOfModule);
-
- var typeBuilder = moduleBuilder.DefineType(
- nameOfType, TypeAttributes.Public, typeof(T));
-
- InjectInterceptor<T>(typeBuilder);
-
- var t = typeBuilder.CreateType();
-
- return Activator.CreateInstance(t) as T;
- }
-
- private static void InjectInterceptor<T>(TypeBuilder typeBuilder)
- {
- // ---- define fields ----
-
- var fieldInterceptor = typeBuilder.DefineField(
- "_interceptor", typeof(Interceptor), FieldAttributes.Private);
-
- // ---- define costructors ----
-
- var constructorBuilder = typeBuilder.DefineConstructor(
- MethodAttributes.Public, CallingConventions.Standard, null);
- var ilOfCtor = constructorBuilder.GetILGenerator();
-
- ilOfCtor.Emit(OpCodes.Ldarg_0);
- ilOfCtor.Emit(OpCodes.Newobj, typeof(Interceptor).GetConstructor(new Type[0]));
- ilOfCtor.Emit(OpCodes.Stfld, fieldInterceptor);
- ilOfCtor.Emit(OpCodes.Ret);
-
- // ---- define methods ----
-
- var methodsOfType = typeof(T).GetMethods(BindingFlags.Public | BindingFlags.Instance);
-
- for (var i = 0; i < methodsOfType.Length; i++)
- {
- var method = methodsOfType[i];
- var methodParameterTypes =
- method.GetParameters().Select(p => p.ParameterType).ToArray();
-
- var methodBuilder = typeBuilder.DefineMethod(
- method.Name,
- MethodAttributes.Public | MethodAttributes.Virtual,
- CallingConventions.Standard,
- method.ReturnType,
- methodParameterTypes);
-
- var ilOfMethod = methodBuilder.GetILGenerator();
- ilOfMethod.Emit(OpCodes.Ldarg_0);
- ilOfMethod.Emit(OpCodes.Ldfld, fieldInterceptor);
-
- // create instance of T
- ilOfMethod.Emit(OpCodes.Newobj, typeof(T).GetConstructor(new Type[0]));
- ilOfMethod.Emit(OpCodes.Ldstr, method.Name);
-
- // build the method parameters
- if (methodParameterTypes == null)
- {
- ilOfMethod.Emit(OpCodes.Ldnull);
- }
- else
- {
- var parameters = ilOfMethod.DeclareLocal(typeof(object[]));
- ilOfMethod.Emit(OpCodes.Ldc_I4, methodParameterTypes.Length);
- ilOfMethod.Emit(OpCodes.Newarr, typeof(object));
- ilOfMethod.Emit(OpCodes.Stloc, parameters);
-
- for (var j = 0; j < methodParameterTypes.Length; j++)
- {
- ilOfMethod.Emit(OpCodes.Ldloc, parameters);
- ilOfMethod.Emit(OpCodes.Ldc_I4, j);
- ilOfMethod.Emit(OpCodes.Ldarg, j + 1);
- ilOfMethod.Emit(OpCodes.Stelem_Ref);
- }
- ilOfMethod.Emit(OpCodes.Ldloc, parameters);
- }
-
- // call Invoke() method of Interceptor
- ilOfMethod.Emit(OpCodes.Callvirt, typeof(Interceptor).GetMethod("Invoke"));
-
- // pop the stack if return void
- if (method.ReturnType == typeof(void))
- {
- ilOfMethod.Emit(OpCodes.Pop);
- }
-
- // complete
- ilOfMethod.Emit(OpCodes.Ret);
- }
- }
- }
- }
|