ILGenerator.Emit动态 MSIL编程(三)之动态代理
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit; public sealed class DynamicProxy
{
private static readonly string AssemblyName = "DynamicProxy",
ModuleName = "DynamicProxy",
TypeName = "DynamicProxy";
private AssemblyBuilder CreateDynamicAssembly<T>() where T : class
{
return AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(AssemblyName + typeof(T).Name),
AssemblyBuilderAccess.Run);
}
private ModuleBuilder CreateDynamicModule<T>() where T : class
{
return CreateDynamicAssembly<T>().DefineDynamicModule(ModuleName + typeof(T).Name);
}
/// <summary>
/// 创建动态代理
/// </summary>
public T CreateDynamicType<T>() where T : class,new()
{
TypeBuilder typeBuilder = CreateDynamicModule<T>().DefineType(TypeName + typeof(T).Name, TypeAttributes.Public |
TypeAttributes.Class, typeof(T));
TypeActuator<T>(typeBuilder);
return Activator.CreateInstance(typeBuilder.CreateType()) as T;
}
private void BuildCtorMethod(Type classType, FieldBuilder fieldBuilder, TypeBuilder typeBuilder)
{
var structureBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard,null);
var ilCtor = structureBuilder.GetILGenerator();
ilCtor.Emit(OpCodes.Ldarg_0);
ilCtor.Emit(OpCodes.Newobj, classType.GetConstructor(Type.EmptyTypes));
ilCtor.Emit(OpCodes.Stfld, fieldBuilder);
ilCtor.Emit(OpCodes.Ret);
}
private void BuildMethod(ILGenerator il, MethodInfo methodInfo, Type[] ParameterTypes)
{
il.Emit(OpCodes.Ldarg_0);
for (int i = ; i < ParameterTypes.Length; i++)
il.Emit(OpCodes.Ldarg_S, (short)(i + ));
il.Emit(OpCodes.Call, methodInfo);
il.Emit(OpCodes.Ret);
}
private void TypeActuator<T>(TypeBuilder builder) where T : class
{
FieldBuilder fieldBuilder = builder.DefineField("_DynamicProxyActuator", typeof(T), FieldAttributes.Private);
BuildCtorMethod(typeof(T), fieldBuilder, builder);
MethodInfo[] info = GetMethodInfo(typeof(T));
foreach (MethodInfo methodInfo in info)
{
if (!methodInfo.IsVirtual && !methodInfo.IsAbstract) continue;
if (methodInfo.Name == "ToString") continue;
if (methodInfo.Name == "GetHashCode") continue;
if (methodInfo.Name == "Equals") continue;
var ParameterTypes = methodInfo.GetParameters().Select(p => p.ParameterType).ToArray();
MethodBuilder methodBuilder = CreateMethod(builder, methodInfo.Name, MethodAttributes.Public | MethodAttributes.Virtual,
CallingConventions.Standard, methodInfo.ReturnType, ParameterTypes);
var ilMethod = methodBuilder.GetILGenerator();
BuildMethod(ilMethod, methodInfo, ParameterTypes);
}
}
private MethodBuilder CreateMethod(TypeBuilder typeBuilder, string name, MethodAttributes attrs, CallingConventions callingConventions,
Type type, Type[] parameterTypes)
{
return typeBuilder.DefineMethod(name, attrs, callingConventions, type, parameterTypes);
}
private MethodInfo[] GetMethodInfo(Type type)
{
return type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
}
}
ILGenerator.Emit动态 MSIL编程(三)之动态代理的更多相关文章
- ILGenerator.Emit动态 MSIL编程(一)之基础
首先在Framework中,Emit相关的类基本都存在于System.Reflection.Emit命名空间下.可见Emit是作为反射的一个元素存在的. Emit能够实现什么?为什么要学习Emit?首 ...
- ILGenerator.Emit动态 MSIL编程(二)之基础
public sealed class ColorToArgb { /// <summary> /// 将十六进制转化为AGRB /// </summary> /// < ...
- C# 使用Emit实现动态AOP框架 (三)
目 录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...
- WIN 下的超动态菜单(三)代码
WIN 下的超动态菜单(一)简介 WIN 下的超动态菜单(二)用法 WIN 下的超动态菜单(三)代码 作者:黄山松,发表于博客园:http://www.cnblogs.com/tomview/ 超动态 ...
- MyBatis学习 之 三、动态SQL语句
目录(?)[-] 三动态SQL语句 selectKey 标签 if标签 if where 的条件判断 if set 的更新语句 if trim代替whereset标签 trim代替set choose ...
- 驱动里执行应用层代码之KeUserModeCallBack(WOW64是由三个动态库wow64.dll wow64win.dll wow64cpu.dll来实现)
在驱动层(ring0)里执行应用层(ring3)代码,这是个老生常谈的技术,而且方法也挺多. 这种技术的本质:其实就是想方设法在驱动层里把应用层代码弄到应用层去执行. 比如在APC异步调用中,KeIn ...
- C#高级编程9-第12章 动态语言扩展
C#高级编程9-第12章 动态语言扩展 dynamic t = new ExpandoObject(); t.Abc = "abc"; t.Value = ; Console.Wr ...
- ASP.NET实现二维码 ASP.Net上传文件 SQL基础语法 C# 动态创建数据库三(MySQL) Net Core 实现谷歌翻译ApI 免费版 C#发布和调试WebService ajax调用WebService实现数据库操作 C# 实体类转json数据过滤掉字段为null的字段
ASP.NET实现二维码 using System;using System.Collections.Generic;using System.Drawing;using System.Linq;us ...
- centos DNS服务搭建 DNS原理 使用bind搭建DNS服务器 配置DNS转发 配置主从 安装dig工具 DHCP dhclient 各种域名解析记录 mydns DNS动态更新 第三十节课
centos DNS服务搭建 DNS原理 使用bind搭建DNS服务器 配置DNS转发 配置主从 安装dig工具 DHCP dhclient 各种域名解析记录 mydns DNS动态更 ...
随机推荐
- leetcode216-Combination Sum III
https://leetcode.com/problems/combination-sum-iii/ 用dfs枚举. class Solution { public: int kk, nn; vect ...
- 基于KNN的newsgroup 18828文本分类器的Python实现
还是同前一篇作为学习入门. 1. KNN算法描述: step1: 文本向量化表示,计算特征词的TF-IDF值 step2: 新文本到达后,根据特征词确定文本的向量 step3 : 在训练文本集中选出与 ...
- Cisco ASA 配置案例---anyconnect拨通后所有流量从服务器端出去
一.目的: 1.Cisco ASA之Lan端能正常上网. 2.anyconnect端所有流量从Cisco ASA的Outside出去. 3.anyconnect端能访问Cisco ASA的Inside ...
- Nginx配置指定媒体类型文件强制下载
由于业务需要,在点击显示链接(如www.xxx.com/2015-01-15/xxx.png)显示媒体资源(如图片.视频.音频.文档),而在点击下载链接(如www.xxx.com/2015-01-15 ...
- esrdtfyghjk
两融余额止跌回升,金融股回落飘绿,千股涨停续演,沪指收复4000点未果涨逾2% 相关报道 [今日收盘]灾后重建激情抢筹 大盘两日反弹500点 [今日收盘]沪指涨近6%重回3700点 未停牌个股九成涨停 ...
- 嵌入式linux应用程序移植方法总结
嵌入式linux应用程序移植方法总结 前段时间一直在做openCapwap的移植和调试工作,现在工作已接近尾声,编写本文档对前段工作进行一个总结,分享下openCapwap移植过程中的经验和感悟.江浩 ...
- Oracle_12c_RAC_service_died问题分析处理
接上篇,通过分析listener日志发现rac1数据库无法连接时出现了listener_20160628.log:28-JUN-2016 07:55:47 * service_died * LsnrA ...
- 关于URI URL URN
刚琢磨.整理了关于escape.encodeURIComponent.encodeURI的知识.突然又对URI有点模糊了,遂整理了以下资源 : 资源一: URL,URI 和URN 的举例理解 资源二: ...
- 无后台的网站 内容暂存json
当网站无后台时,将数据暂存储为json文档,然后通过调用json文件获取数据填充前端页面 存储json格式的文件 [ { "id": 1, "cat": &qu ...
- html+css基础知识总结
1.HTML书写的基本规范 img标签必须得写alt="" 标签名和属性名字必须小写 引号必须用双引号 双标签必须有闭合标签 单标 ...