最近在做服务的细粒度治理,统一管理所有服务的方法、参数、返回值信息。方便后续的各个模块之间的对接和协作。

目前系统中所有的服务,管理到接口契约粒度,即服务接口声明和服务接口实现。要做服务的细粒度治理:

首先需要将服务的各个方法信息全部反射出来,然后再统一管理。

大致的思路是这样的:

1. 下载所有最新的服务包(dll文件集合)

2. 获取所有的服务定义信息

3. 反射加载出每个服务详细的方法信息(方法名、参数、返回值等)

一、下载所有最新的服务包

系统中几百个服务,几十个服务组,每个服务都对应一个服务包(dll文件集合),通过FTP将所有最新的服务包下载到本地,释放出来

每个服务包一个文件夹

二、获取所有的服务定义信息

这个也很简单,从主数据库中获取最新的服务定义信息即可,放到本地内存的一个集合中

三、反射加载出每个服务详细的方法信息(方法名、参数、返回值等)

循环遍历每个服务,Reflect每个接口信息,那么问题来了?

很多服务之间是有依赖的,所以有服务组的概念,反射加载时,必须指定:

AppDomain.CurrentDomain.AppendPrivatePath(servicePath);

然后,反射加载各个接口和接口实现

1  Assembly asm = Assembly.Load(metadata.Invoke.UserDefineAssemble);
2  Type type = asm.GetType(metadata.Invoke.UserDefineClass, true, true);

这样做,通过发现Assembly加载不起来,因为反射加载时,很多依赖的dll找不到,或者不是最新版本(服务有多版本设计)。

具体反射的dll加载顺序,请大家参考MSDN:

https://docs.microsoft.com/en-us/dotnet/framework/deployment/how-the-runtime-locates-assemblies

如何解决这个问题?其实很简单的一个需要,解析Dll中的 Method Table.

此时,想到了ILSpy,Reflector,这些组件实现了Dll的反射加载,找找看看相关的SDK。

找着找着发现了Mono.Cecil.

http://www.mono-project.com/docs/tools+libraries/libraries/Mono.Cecil/

Cecil is a library written by Jb Evain to generate and inspect programs and libraries in the ECMA CIL format.

With Cecil, you can load existing managed assemblies, browse all the contained types, modify them on the fly and save back to the disk the modified assembly.

直接Nuget引用。

关键的几个dll:

using Mono.Cecil;

同时,为了方便加载dll和处理服务组的dll,将所有服务包的dll递归放到一个文件夹中,同名Dll以最新修改时间为准。
上述文件准备工作就绪后,可以编码了:

 1 using HSF.Service.Govermance.SPI;
 2 using Mono.Cecil;
 3 using System;
 4 using System.Collections.Generic;
 5 using System.IO;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Threading.Tasks;
 9
10 namespace HSF.Service.Govermance.Service
11 {
12     /// <summary>
13     /// 反射加载工具类
14     /// </summary>
15     class ReflectionUtils
16     {
17         public static List<HSFServiceMethod> GetMethods(HSFServiceMetadataEntity metaData, string path)
18         {
19             var result = new List<HSFServiceMethod>();
20             var file = Path.Combine(path, metaData.ServiceImplAssembly.Replace(" ", ""));
21             var assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(file);
22             TypeDefinition type = assembly.MainModule.GetType(metaData.ServiceImplClass);
23             var methods = type.Methods;
24             foreach (var method in methods)
25             {
26                 var hsfMethod = new HSFServiceMethod();
27                 hsfMethod.ID = Guid.NewGuid().ToString();
28                 hsfMethod.ServiceID = metaData.ServiceID;
29                 hsfMethod.MethodName = method.Name;
30                 hsfMethod.ReturnType = method.ReturnType.FullName;
31                 hsfMethod.Parameters = new List<HSFServiceParameter>();
32                 var methodName = method.Name;
33                 if (method.Parameters != null && method.Parameters.Count > 0)
34                 {
35                     foreach (var parameter in method.Parameters)
36                     {
37                         HSFServiceParameter para = new HSFServiceParameter()
38                         {
39                             ID = Guid.NewGuid().ToString(),
40                             MethodID = hsfMethod.ID,
41                             ServiceID = metaData.ServiceID,
42                             ParameterName = parameter.Name,
43                             ParameterOrder = parameter.Sequence,
44                             ParameterType = parameter.ParameterType.FullName,
45                         };
46
47                         hsfMethod.Parameters.Add(para);
48                     }
49                 }
50
51                 result.Add(hsfMethod);
52             }
53
54             return result;
55         }
56     }
57 }

所有的服务的方法、参数、返回值信息全部搞定。

周国庆

2017/9/29

转载于:https://www.cnblogs.com/tianqing/p/7610560.html

巧用Mono.Cecil反射加载类型和方法信息相关推荐

  1. 运用Mono.Cecil 反射读取.NET程序集元数据

    CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...

  2. 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习)

    原文:利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习) Mono.Cecil是一个强大的MSIL的注入工具,利用它可以实现动态创建程序集,也可以实现拦截器横向切入动态方法,甚至还 ...

  3. 使用Mono.Cecil辅助ASP.NET MVC使用dynamic类型Model

    使用Mono.Cecil辅助ASP.NET MVC使用dynamic类型Model 2011-09-06 00:21 by 老赵, 8645 visits 这也是之前在珠三角技术沙龙上的示例之一,解决 ...

  4. 编译时MSIL注入--实践Mono Cecil(1)

    紧接上两篇浅谈.NET编译时注入(C#-->IL)和浅谈VS编译自定义编译任务-MSBuild Task(csproject),在第一篇中我们简单研究了c#语法糖和PostSharp的MSIl注 ...

  5. java反射 数组类,乐字节Java反射之三:方法、数组、类加载器和类的生命周期

    继续讲述Java反射之三:方法.数组.类加载器 一.方法 获取所有方法(包括父类或接口),使用Method即可. public static void test() throwsException { ...

  6. C#的反射机制调用方法

    .NET的反射(Reflection)是非常完善和强大的,例如有名的.NET反编译工具Red Gate's .NET Reflector就是使用了.NET自身的反射机制,这里有一个比较简单的实例(使用 ...

  7. JUnit 3.8 通过反射测试私有方法

    测试私有(private)的方法有两种: 1)把目标类的私有方法(修饰符:private)修改为(public),不推荐,因为修改了源程序不佳 2)通过反射 (推荐) 代码演示: 目标程序 Priva ...

  8. python_day21面向对象的进阶(反射,内置方法,)

    # 两个内置函数 *# 反射 *****# 内置方法 *** # 类(定义) # 静态属性 类属性(变量) 直接写在类中,全大写 # 动态属性 方法(函数) self # 类方法 @classmeth ...

  9. 使用计算机的方法视频,怎么直接把电脑的视频共享给电视?巧用当贝市场,四种方法供你选...

    怎么直接把电脑的视频共享给电视?巧用当贝市场,四种方法供你选 2021年03月22日 21:13作者:网络编辑:王动 分享 近日,有用户问到如何直接把电脑的视频共享给电视?今天,小编就给大家带来了全网 ...

最新文章

  1. python重难点之装饰器详解
  2. mern技术栈好处?_通过构建运动追踪器应用程序来学习MERN堆栈(MERN教程)
  3. ADC/DAC设计常见40问
  4. 无法获取到图片的宽高
  5. python六十五:描述符(__get__, __set__, __delete__)
  6. 系统集成资质培训 - 标准系列 -软件文档管理指南
  7. Leetcode--342. 4的幂
  8. php dom 丢失内容,PHP DOMDocument缺失
  9. 拿起电话就开始给(飞鸽传书3.0)
  10. 风靡全球的儿童编程语言:Scratch
  11. 树莓派-linux的多种启动自运行方式
  12. 【问题】父套子时,‘阻止子元素的外边距传递给父元素’与闭合浮动
  13. OpenCV3编程入门(毛星云)读书笔记(一)
  14. 十大顶级大数据可视化工具
  15. 记录下对游戏主机配置的个人理解与心得
  16. 三点共线判断方法分析
  17. 探究MySQL的索引结构选型
  18. NS3中“E: package ‘gnuplot‘ has no installation candidate”问题解决方案
  19. 《微机原理第五版》期末知识总结(第五章---第七章)
  20. Step7编程语言编程概述结构

热门文章

  1. Spring Cloud学习系列第六篇【分布式配置中心】
  2. 2018.3.29 网页中嵌套网页的两种方法
  3. 单链表的几个基本操作
  4. stm32f4 RAM中运行程序 读保护设置
  5. [POI 2009] gas 贪心
  6. NSRunLoop概述(转)
  7. JRE System Library、Referenced Libraries、Web App Libraries的含义
  8. 3889=神奇的函数
  9. 【Win 10 应用开发】UI Composition 札记(二):基本构件
  10. 读《大型网站技术架构:核心原理与案例分析》第一章:大型网站架构演化