您现在的位置是:网站首页> 内容页

利用.NET Core类库System.Reflection.DispatchProxy实现简易Aop

  • 兴发xf132官方网站
  • 2019-08-15
  • 282人已阅读
简介Aop即是面向切面编程,众多Aop框架里Castle是最为人所知的,另外还有死去的Spring.NET,当然,.NETCore社区新秀AspectCore在性能与功能上都非常优秀,已

Aop即是面向切面编程,众多Aop框架里Castle是最为人所知的,另外还有死去的Spring.NET,当然,.NET Core社区新秀AspectCore在性能与功能上都非常优秀,已经逐渐被社区推崇和有越来越多的人使用。感谢柠檬同学的礼物!

如果大家出于自身需求或者学习,想实现一个Aop,是不是觉得一来就要使用Emit去做?最近我了解到了System.Reflection.DispatchProxy这个corefx类库,已经实现了动态代理功能。

下面演示一下它的使用方法:

class Program{ static void Main(string[] args) { //创建代理类,并把SamepleProxy作为拦截器注入 var samepleProxy = (targetInterface)SamepleProxy.Create<targetInterface SamepleProxy>() //执行接口方法 samepleProxy.Write("here is invoke by proxy") }}//需要被生成代理实例的接口public interface targetInterface{ //这个方法会被代理类实现 void Write(string writesomeshing)}public class SamepleProxy : DispatchProxy{ /// <summary> /// 拦截调用 /// </summary> /// <param name="method">所拦截的方法信息</param> /// <param name="parameters">所拦截方法被传入的参数指</param> /// <returns></returns> protected override object Invoke(MethodInfo targetMethod object[] args) { Console.WriteLine(args[0]) return null }}

System.Reflection.DispatchProxy只有一个Api,就是objecct Create<TTProxy>() where TProxy:DispatchProxy约束了只能传入泛型参数,并不能从方法传入类型,这就会带来很多问题。而更可气的是,给官方提了issue之后,还是不给增加这个api……幸好,在那个issue下,issue作者提供了一个解决方案,就是用反射来构造这个泛型方法。我还在这基础上,封装了一下,加入了传入拦截器实例和传入拦截器构造方法参数的功能。

/// <summary>/// 拦截器接口/// </summary>public interface IInterceptor{ /// <summary> /// 拦截器调用 /// </summary> /// <param name="target">代理实例</param> /// <param name="method">所拦截的方法</param> /// <param name="parameters">所拦截方法传入的参数值</param> /// <returns>返回值会传递给方法返回值</returns> object Intercept(object target MethodInfo method object[] parameters)}

拦截器要实现这个接口,下面是对DispatchProxy的封装,实现更多创建代理实例的方法

public class ProxyGenerator : DispatchProxy{ private IInterceptor interceptor { get set } private static object proxy { get set } /// <summary> /// 创建代理实例 /// </summary> /// <param name="targetType">所要代理的接口类型</param> /// <param name="interceptor">拦截器</param> /// <returns>代理实例</returns> 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 } /// <summary> /// 创建代理实例 /// </summary> /// <param name="targetType">所要代理的接口类型</param> /// <param name="interceptorType">拦截器类型</param> /// <param name="parameters">拦截器构造函数参数值</param> /// <returns>代理实例</returns> 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 } /// <summary> /// 创建代理实例 TTarget:所要代理的接口类型 TInterceptor:拦截器类型 /// </summary> /// <param name="parameters">拦截器构造函数参数值</param> /// <returns>代理实例</returns> public static TTarget Create<TTarget TInterceptor>(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<targetInterface SamepleProxy>() 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

1 0 9)

文章评论

Top