巧用Mono.Cecil反射加载类型和方法信息
最近在做服务的细粒度治理,统一管理所有服务的方法、参数、返回值信息。方便后续的各个模块之间的对接和协作。
目前系统中所有的服务,管理到接口契约粒度,即服务接口声明和服务接口实现。要做服务的细粒度治理:
首先需要将服务的各个方法信息全部反射出来,然后再统一管理。
大致的思路是这样的:
1. 下载所有最新的服务包(dll文件集合)
2. 获取所有的服务定义信息
3. 反射加载出每个服务详细的方法信息(方法名、参数、返回值等)
一、下载所有最新的服务包
系统中几百个服务,几十个服务组,每个服务都对应一个服务包(dll文件集合),通过FTP将所有最新的服务包下载到本地,释放出来
每个服务包一个文件夹
二、获取所有的服务定义信息
这个也很简单,从主数据库中获取最新的服务定义信息即可,放到本地内存的一个集合中
三、反射加载出每个服务详细的方法信息(方法名、参数、返回值等)
循环遍历每个服务,Reflect每个接口信息,那么问题来了?
很多服务之间是有依赖的,所以有服务组的概念,反射加载时,必须指定:
AppDomain.CurrentDomain.AppendPrivatePath(servicePath);
然后,反射加载各个接口和接口实现
Assembly asm = Assembly.Load(metadata.Invoke.UserDefineAssemble);
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以最新修改时间为准。
上述文件准备工作就绪后,可以编码了:
using HSF.Service.Govermance.SPI;
using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace HSF.Service.Govermance.Service
{
/// <summary>
/// 反射加载工具类
/// </summary>
class ReflectionUtils
{
public static List<HSFServiceMethod> GetMethods(HSFServiceMetadataEntity metaData, string path)
{
var result = new List<HSFServiceMethod>();
var file = Path.Combine(path, metaData.ServiceImplAssembly.Replace(" ", ""));
var assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(file);
TypeDefinition type = assembly.MainModule.GetType(metaData.ServiceImplClass);
var methods = type.Methods;
foreach (var method in methods)
{
var hsfMethod = new HSFServiceMethod();
hsfMethod.ID = Guid.NewGuid().ToString();
hsfMethod.ServiceID = metaData.ServiceID;
hsfMethod.MethodName = method.Name;
hsfMethod.ReturnType = method.ReturnType.FullName;
hsfMethod.Parameters = new List<HSFServiceParameter>();
var methodName = method.Name;
if (method.Parameters != null && method.Parameters.Count > )
{
foreach (var parameter in method.Parameters)
{
HSFServiceParameter para = new HSFServiceParameter()
{
ID = Guid.NewGuid().ToString(),
MethodID = hsfMethod.ID,
ServiceID = metaData.ServiceID,
ParameterName = parameter.Name,
ParameterOrder = parameter.Sequence,
ParameterType = parameter.ParameterType.FullName,
}; hsfMethod.Parameters.Add(para);
}
} result.Add(hsfMethod);
} return result;
}
}
}
所有的服务的方法、参数、返回值信息全部搞定。
周国庆
2017/9/29
巧用Mono.Cecil反射加载类型和方法信息的更多相关文章
- 运用Mono.Cecil 反射读取.NET程序集元数据
CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...
- Mono.Cecil
Mono Cecil十分强大,强大到可以静态注入程序集(注入后生成新的程序集)和动态注入程序集(注入后不改变目标程序集,只在运行时改变程序集行为),它甚至可以用来调试PDB MDB调试符号格式文件. ...
- C# Asp.net中的AOP框架 Microsoft.CCI, Mono.Cecil, Typemock Open-AOP API, PostSharp -摘自网络 (可以利用反射 Attribute 进行面向切面编程 可以用在记录整个方法的Log方面)
Both Microsoft.CCI and Mono.Cecil are low-level, and don't validate produced assemblies. It takes lo ...
- 使用Mono Cecil 动态获取运行时数据 (Atribute形式 进行注入 用于写Log) [此文报考 xxx is declared in another module and needs to be imported的解决方法]-摘自网络
目录 一:普通写法 二:注入定义 三:Weave函数 四:参数构造 五:业务编写 六:注入调用 7. 怎么调用别的程序集的方法示例 8. [is declared in another module ...
- 基于Mono.Cecil的静态注入
Aop注入有2种方式:动态注入和静态注入,其中动态注入有很多实现了 动态注入有几种方式: 利用Remoting的ContextBoundObject或MarshalByRefObject. 动态代理( ...
- 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习)
原文 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习) Mono.Cecil是一个强大的MSIL的注入工具,利用它可以实现动态创建程序集,也可以实现拦截器横向切入动态方法,甚至还 ...
- 教你怎么用Mono Cecil - 动态注入 (注意代码的注释)
原文 教你怎么用Mono Cecil - 动态注入 (注意代码的注释) 使用 Mono Cecil 进行反编译:using Mono.Cecil; using Mono.Cecil.Cil; //.. ...
- Mono.Cecil 初探(一):实现AOP
序言 本篇文章介绍基于Mono.Cecil实现静态AOP的两种方式:无交互AOP和交互式AOP. 概念介绍 Mono.Cecil:一个可加载并浏览现有程序集并进行动态修改并保存的.NET框架. AOP ...
- 使用 Mono.Cecil 辅助 Unity3D 手游进行性能测试
Unity3D 引擎在 UnityEngine 名字空间下,提供了 Profiler 类(Unity 5.6 开始似乎改变了这个名字空间),用于辅助对项目性能进行测试.以 Android 平台为例 ...
随机推荐
- jQuery圣诞雪花
<script type="text/javascript"> $(function(){ var d="<div class='y_snow'> ...
- 高新技术---枚举及部分JDK1.5新特性
第一讲 枚举 一.概述 这里说的枚举,不是集合vector的特有枚举迭代器,而是JDK1.5的一个新特性.之所以单独拿它开刷,是这个知识点比较重要,同时相对来说比较难理解一些. 为什么要有枚举 ...
- 高阶自定义View --- 粒子变幻、隧道散列、组合文字
高阶自定义View --- 粒子变幻.隧道散列.组合文字 作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:h ...
- Android开发——xml知识之xml可绘制对象简介
引言:摘录Android用户界面设计 Android支持各类xml可绘制对象,其中一些可绘制对象可用于实现让一个资源使用多个图片文件,另外一些则允许你在xml中真正地指定颜色,还有一些你从来都不会用到 ...
- CSS中的路径裁剪样式clip-path
前面的话 CSS借鉴了SVG裁剪的概念,设置了clip-path样式,本文将详细介绍路径裁剪clip-path 概述 clip-path属性可以防止部分元素通过定义的剪切区域来显示,仅通过显示的特殊区 ...
- MIT6.828课程JOS在macOS下的环境配置
本文将介绍如何在macOS下配置MIT6.828 JOS实验的环境. 写JOS之前,在网上搜寻JOS的开发环境,很多博客和文章都提到"不是32位linux就不好配置,会浪费大量时间在配置环境 ...
- nhibernate教程(4)--条件查询(Criteria Query)
NHibernate之旅(4):探索查询之条件查询(Criteria Query) 2008-10-16 18:20 by 李永京, 44341 阅读, 43 评论, 收藏, 编辑 本节内容 NHi ...
- C# 委托、匿名方法、lambda简介
在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个First不 ...
- 团队作业8——第二次项目冲刺(Beta阶段)--第三天
一.Daily Scrum Meeting照片 二.燃尽图 三.项目进展 学号 成员 贡献比 201421123001 廖婷婷 16% 201421123002 翁珊 16% 201421123004 ...
- 扫雷游戏制作过程(C#描述):第三节、雷区绘制
前言 这里给出教程原文地址. 该项目已经放在github上托管. 绘制雷区 这一节我们主要涉及界面中雷区的绘制.绘制雷区需要三个变量来保存雷区行数.列数.以及地雷的数量.而且我们希望能够自动获取上次游 ...