.NET Core类库System.Reflection.DispatchProxy实现简易Aop的方法
更新时间:2018年12月30日 10:46:45 作者:ElderJames
这篇文章主要给大家介绍了关于.NET Core类库System.Reflection.DispatchProxy实现简易Aop的相关资料,文中通过示例代码结束的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
前言
aop即是面向切面编程,众多Aop框架里Castle是最为人所知的,另外还有死去的Spring.NET,当然,.NET Core社区新秀AspectCore在性能与功能上都非常优秀,已经逐渐被社区推崇和有越来越多的人使用。感谢柠檬同学的礼物!
如果大家出于自身需求或者学习,想实现一个Aop,是不是觉得一来就要使用Emit去做?最近我了解到了System.Reflection.DispatchProxy这个corefx类库,已经实现了动态代理功能。
1|1System.Reflection.DispatchProxy
下面演示一下它的使用方法:
class Program
{
static void Main(string[] args)
{
//创建代理类,并把SampleProxy作为拦截器注入
var sampleProxy = (targetInterface)SampleProxy.Create<targetInterface, SampleProxy>();
//执行接口方法
sampleProxy.Write(“here is invoke by proxy”);
}
}
//需要被生成代理实例的接口
public interface targetInterface
{
//这个方法会被代理类实现
void Write(string writesomeshing);
}
public class SampleProxy : 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;
}
}
2|0改造成一款简易AOP
2|1为什么?
System.Reflection.DispatchProxy只有一个Api,就是objecct Create<T,TProxy>() where TProxy:DispatchProxy,约束了只能传入泛型参数,并不能从方法传入类型,这就会带来很多问题。而更可气的是,给官方提了issue之后,还是不给增加这个api……
2|2改造方法
幸好,在那个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; }
/// <summary>
/// 创建代理实例
/// </summary>
/// <param name=”targetType”>所要代理的接口类型</param>
/// <param name=”interceptor”>拦截器</param>
/// <returns>代理实例</returns>
public static object Create(Type targetType, IInterceptor interceptor)
{
object proxy = GetProxy(targetType);
((ProxyGenerator)proxy).CreateInstance(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);
((ProxyGenerator)proxy).CreateInstance(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
{
var proxy = GetProxy(typeof(TTarget));
((ProxyGenerator)proxy).CreateInstance(typeof(TInterceptor), parameters);
return (TTarget)proxy;
}
private static object GetProxy(Type targetType)
{
var callexp = Expression.Call(typeof(DispatchProxy), nameof(DispatchProxy.Create), new[] { targetType, typeof(ProxyGenerator) });
return Expression.Lambda<Func<object>>(callexp).Compile()();
}
private void CreateInstance(Type interceptorType, object[] parameters)
{
var ctorParams = parameters.Select(x => x.GetType()).ToArray();
var paramsExp = parameters.Select(x => Expression.Constant(x));
var newExp = Expression.New(interceptorType.GetConstructor(ctorParams), paramsExp);
this.interceptor = Expression.Lambda<Func<IInterceptor>>(newExp).Compile()();
}
private void CreateInstance(IInterceptor interceptor)
{
this.interceptor = interceptor;
}
protected override object Invoke(MethodInfo method, object[] parameters)
{
return this.interceptor.Intercept(method, parameters);
}
}
2|3使用方法
class Program
{
static void Main(string[] args)
{
var poxy1 = (targetInterface)ProxyGenerator.Create(typeof(targetInterface), new SampleProxy(“coreproxy1”));
poxy1.Write(“here was invoked”); //—> “here was invoked by coreproxy1”
var poxy2 = (targetInterface)ProxyGenerator.Create(typeof(targetInterface), typeof(SampleProxy), “coreproxy2”);
poxy2.Write(“here was invoked”); //—> “here was invoked by coreproxy2”
var poxy3 = ProxyGenerator.Create<targetInterface, SampleProxy>(“coreproxy3”);
poxy3.Write(“here was invoked”); //—> “here was invoked by coreproxy3″
}
}
public class SampleProxy : IInterceptor
{
private string proxyName { get; }
public SampleProxy(string name)
{
this.proxyName = name;
}
public object Intercept(MethodInfo method, object[] parameters)
{
Console.WriteLine(parameters[0] + ” by ” + proxyName);
return null;
}
}
public interface targetInterface
{
void Write(string writesome);
}
3|0总结
总结一下就是,微软爸爸给我们的这个轮子还是即轻便又很好用的。
本文的实例代码可以在我的github上找到:github.com/ElderJames/CoreProxy
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对华域联盟的支持。
您可能感兴趣的文章:记一次EFCore类型转换错误及解决方案EFCore 通过实体Model生成创建SQL Server数据库表脚本从EFCore上下文的使用到深入剖析DI的生命周期最后实现自动属性注入如何在Asp.Net Core中集成Refit.net core实用技巧——将EF Core生成的SQL语句显示在控制台中.net EF Core专题:EF Core 读取数据时发生了什么?.net core EF Core调用存储过程的方式详解.Net Core 权限验证与授权(AuthorizeFilter、ActionFilterAttribute)在.NET Core类库中使用EF Core迁移数据库到SQL Server的方法CodeFirst从零开始搭建Asp.Net Core2.0网站.Net Core中使用ref和Span<T>提高程序性能的实现代码详解EFCore中的导航属性
core
类库
system.reflection.dispatchproxy
相关文章
asp.net中Timer无刷新定时器的实现方法这篇文章主要介绍了asp.net中Timer无刷新定时器的实现方法,是一个非常具有实用价值的技巧,需要用到Ajax技术,需要的朋友可以参考下 2014-08-08
Springboot服务Docker化自动部署的实现方法这篇文章主要介绍了Springboot服务Docker化自动部署的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 2021-03-03
Ajax实现异步刷新验证用户名是否已存在的具体方法由于要做一个注册页面,看到许多网站上都是使用Ajax异步刷新验证用户名是否可用的,所以自己也动手做一个小实例 2014-02-02
ASP.NET Ajax级联DropDownList实现代码我想大家对Ajax已耳熟能详。自web 2.0概念出现以后,提供更好的用户体验变得越来越重要。那么今天我来讲解一下如何使用ASP.NET Ajax和web service构建无刷新级联DropDownList(以下简称为级联DDL)。完成的效果图 2008-12-12
Asp.net的GridView控件实现单元格可编辑方便用户使用考虑到用户使用方便,减少弹出页面,采用点“编辑”按钮无需弹出页面直接当前行的单元格内容就能编辑,思路及代码如下,有此需求的朋友可以参考下,希望对大家有所帮助 2013-08-08
Asp.Net、asp实现的搜索引擎网址收录检查程序这篇文章主要介绍了Asp.Net、asp实现的搜索引擎网址收录检查程序,即实现检查一个网址是否被搜索引擎收录功能的小程序,需要的朋友可以参考下 2014-08-08
ASP.NET性能优化小结(ASP.NET&C#)ASP.NET性能优化,提高页面的执行效率与下载速度,等很多需要考虑的细节,编程人员值得参考下。 2011-01-01
ASP.NET Core对Controller进行单元测试的完整步骤这篇文章主要给大家介绍了关于ASP.NET Core对Controller进行单元测试的完整步骤,文中通过示例代码介绍的非常详细,对大家学习或者使用ASP.NET Core具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧 2020-06-06
实现Asp与Asp.Net共享Session的方法这篇文章主要介绍了实现Asp与Asp.Net共享Session的方法,需要的朋友可以参考下 2014-08-08
详解ASP.NET Razor 语法这篇文章主要介绍了ASP.NET Razor 语法的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下 2020-07-07
最新评论

评论(0)