netcore之动态代理(微服务专题)

动态代理配合rpc技术调用远程服务,不用关注细节的实现,让程序就像在本地调用以用。

因此动态代理在微服务系统中是不可或缺的一个技术。网上看到大部分案例都是通过反射自己实现,且相当复杂。编写和调试相当不易,我这里提供里一种简便的方式来实现动态代理。

1、创建我们的空白.netcore项目 

通过vs2017轻易的创建出一个.netcore项目

2、编写Startup.cs文件

默认Startup 没有构造函数,自行添加构造函数,带有  IConfiguration 参数的,用于获取项目配置,但我们的示例中未使用配置

在ConfigureServices 配置日志模块,目前core更新的很快,日志的配置方式和原来又很大出入,最新的配置方式如下

添加路由过滤器,监控一个地址,用于调用我们的测试代码。netcore默认没有UTF8的编码方式,所以要先解决UTF8编码问题,否则将在输出中文时候乱码。

这里注意 Map  内部传递了参数 applicationBuilder ,千万不要 使用Configure(IApplicationBuilder app, IHostingEnvironment env ) 中的app参数,否则每次请求api/health时候都将调用这个中间件(app.Run会短路期后边所有的中间件),

3、代理

netcore 已经为我们完成了一些工作,提供了DispatchProxy 这个类

这个类提供了一个实例方法,一个静态方法:

Invoke(MethodInfo targetMethod, object[] args) (注解1)

Create<T, TProxy>()(注解2)

Create 创建代理的实例对象,实例对象在调用方法时候会自动执行Invoke

首先我们创建一个动态代理类  ProxyDecorator<T>:DispatchProxy  需要继承DispatchProxy  。

在DispatchProxy 的静态方法  Create<T, TProxy>()中要求 TProxy : DispatchProxy

ProxyDecorator 重写  DispatchProxy的虚方法invoke 

我们可以在ProxyDecorator 类中添加一些其他方法,比如:异常处理,MethodInfo执行前后的处理。

重点要讲一下 

ProxyDecorator 中需要传递一个 T类型的变量 decorated 。

因为  DispatchProxy.Create<T, ProxyDecorator<T>>(); 会创建一个新的T的实例对象 ,这个对象是代理对象实例,我们将 decorated 绑定到这个代理实例上

接下来这个代理实例在执行T类型的任何方法时候都会用到 decorated,因为 [decorated] 会被传给  targetMethod.Invoke(decorated, args)   (targetMethod 来自注解1) ,invoke相当于执行

这样说的不是很明白,我们直接看代码

代码比较简单,相信大家都看的懂,关键的代码和核心的系统代码已经加粗和加加粗+红 标注出来了

DispatchProxy<T> 类中有两种创建代理实例的方法

我们看一下第一种比较简单的创建方法

代码中 UserService 和 IUserService 是一个class和interface  自己实现即可 ,随便写一个接口,并用类实现,任何一个方法就行,下面只是演示调用方法时候会执行什么,这个方法本身在岩石中并不重要。

 由于ProxyDecorator 中并未注入相关事件,所以我们在调用 user.GetUserName(222) 时候看不到任何特别的输出。下面我们演示一个相对复杂的调用方式。

IUserService user = serviceProxy.Create(userService, beforeEvent, afterEvent); 在创建代理实例时候传递了beforEvent 和 afterEvent,这两个事件处理函数是我们在业务中定义的

void beforeEvent(MethodInfo methodInfo, object[] arges){System.Diagnostics.Debug.WriteLine("方法执行前");}

void afterEvent(MethodInfo methodInfo, object[] arges){System.Diagnostics.Debug.WriteLine("执行后的事件");}

在代理实例执行接口的任何方法的时候都会执行  beforeEvent,和 afterEvent 这两个事件(请参考Invoke(MethodInfo targetMethod, object[] args) 方法的实现)

在我们的示例中将会在vs的 输出 面板中看到 

方法执行前

“方法输出的值”

执行后事件

我们看下运行效果图:

 

 这是 user.GetUserName(222) 的运行结果

 控制台输出结果

原文链接:https://www.cnblogs.com/netqq/p/11452374.html

.NET社区新闻,深度好文,欢迎访问文章汇总 ;