如果大家出于自身需求或者学习,想实现一个Aop,是不是觉得一来就要使用Emit去做?最近我了解到了System.Reflection.DispatchProxy这个corefx类库,已经实现了动态代理功能。
下面演示一下它的使用方法:
class Program{ static void Main(string[] args) { //创建代理类,并把SamepleProxy作为拦截器注入
var samepleProxy = (targetInterface)SamepleProxy.Create(); //执行接口方法
samepleProxy.Write("here is invoke by proxy");
}
}//需要被生成代理实例的接口public interface targetInterface{ //这个方法会被代理类实现
void Write(string writesomeshing);
}public class SamepleProxy : DispatchProxy{ ///
/// 拦截调用
///
/// 所拦截的方法信息
/// 所拦截方法被传入的参数指
///
protected override object Invoke(MethodInfo targetMethod, object[] args) {
Console.WriteLine(args[0]); return null;
}
} System.Reflection.DispatchProxy只有一个Api,就是objecct Create
幸好,在那个issue下,issue作者提供了一个解决方案,就是用反射来构造这个泛型方法。我还在这基础上,封装了一下,加入了传入拦截器实例和传入拦截器构造方法参数的功能。
////// 拦截器接口/// public interface IInterceptor{ ////// 拦截器调用 /// /// 代理实例 /// 所拦截的方法 /// 所拦截方法传入的参数值 ///返回值会传递给方法返回值 object Intercept(object target, MethodInfo method, object[] parameters); }
拦截器要实现这个接口,下面是对DispatchProxy的封装,实现更多创建代理实例的方法
public class ProxyGenerator : DispatchProxy{ private IInterceptor interceptor { get; set; } private static object proxy { get; set; } ///
/// 创建代理实例
///
/// 所要代理的接口类型
/// 拦截器
/// 代理实例
public static object Create(Type targetType, IInterceptor interceptor) { object proxy = GetProxy(targetType);
MethodInfo method = typeof(ProxyGenerator).GetMethod(nameof(CreateInstance), BindingFlags.NonPublic | BindingFlags.Instance, Type.DefaultBinder, new[] { typeof(IInterceptor) }, null);
method.Invoke(proxy, new object[] { interceptor }); return proxy;
} ///
/// 创建代理实例
///
/// 所要代理的接口类型
/// 拦截器类型
/// 拦截器构造函数参数值
/// 代理实例
public static object Create(Type targetType, Type interceptorType, params object[] parameters) { object proxy = GetProxy(targetType);
MethodInfo method = typeof(ProxyGenerator).GetMethod(nameof(CreateInstance), BindingFlags.NonPublic | BindingFlags.Instance, Type.DefaultBinder, new[] { typeof(Type), typeof(object[]) }, null);
method.Invoke(proxy, new object[] { interceptorType, parameters }); return proxy;
} ///
/// 创建代理实例 TTarget:所要代理的接口类型 TInterceptor:拦截器类型
///
/// 拦截器构造函数参数值
/// 代理实例
public static TTarget Create(params object[] parameters) where TInterceptor : IInterceptor
{ object proxy = GetProxy(typeof(TTarget));
MethodInfo method = typeof(ProxyGenerator).GetMethod(nameof(CreateInstance), BindingFlags.NonPublic | BindingFlags.Instance, Type.DefaultBinder, new[] { typeof(Type), typeof(object[]) }, null);
method.Invoke(proxy, new object[] { typeof(TInterceptor), parameters }); return (TTarget)proxy;
} private static object GetProxy(Type targetType) {
MethodInfo method = typeof(DispatchProxy).GetMethod(nameof(DispatchProxy.Create), new Type[] { });
method = method.MakeGenericMethod(targetType, typeof(ProxyGenerator));
proxy = method.Invoke(null, null); return proxy;
} private void CreateInstance(Type interceptorType, object[] parameters) { this.interceptor = (IInterceptor)Activator.CreateInstance(interceptorType, parameters);
} private void CreateInstance(IInterceptor interceptor) { this.interceptor = interceptor;
} protected override object Invoke(MethodInfo method, object[] parameters) { return this.interceptor.Intercept(proxy, method, parameters);
}
} 使用方法:
class Program{ static void Main(string[] args) { // var poxy = (targetInterface)ProxyGenerator.Create(typeof(targetInterface), new SamepleProxy());
// 或
//var poxy = (targetInterface)ProxyGenerator.Create(typeof(targetInterface), typeof(SamepleProxy));
// 或
var poxy = ProxyGenerator.Create();
poxy.Write("here is invoked by coreproxy");
}
}public class SamepleProxy : IInterceptor{ public object Intercept(object target, MethodInfo method, object[] parameters) {
Console.WriteLine(parameters[0]); return null;
}
}public interface targetInterface{ void Write(string writesome);
} 总结一下就是,微软爸爸给我们的这个轮子还是即轻便又很好用的。
本文的实例代码可以在我的github上找到:https://github.com/ElderJames/CoreProxy
原文出处:https://www.cnblogs.com/ElderJames/p/implement-simple-Aop-using-a-dotnet-core-library-System-Reflection-DispatchProxy.html



