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动态更 ...
随机推荐
- 初学AOP
src\dayday\Count.java package dayday;import org.springframework.stereotype.Component;/** * Created b ...
- java 调用 sql server存储过程
Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这样就可以提高存储过程的性能. Ø ...
- php大力力 [049节] php函数implode()
implode()[1] 函数返回一个由数组元素组合成的字符串. 注释:implode() 函数接受两种参数顺序.但是由于历史原因,explode() 是不行的,您必须保证 separator 参数 ...
- SIP模块版本错误问题:the sip module implements API v??? but XXX module requires API v???
系统安装了python 2.7,继续安装PyQt4,于是依次下载sip.pyqt4源码进行安装.用以下代码测试: import PyQt4.QtGui 显示出错.错误信息:the sip module ...
- linux驱动之USB驱动程序
1. USB是主从结构的 所有的USB传输,都是从USB主机这方发起:USB设备没有"主动"通知USB主机的能力. 例子:USB鼠标滑动一下立刻产生数据,但是它没有能力通知PC机来 ...
- 推荐一些不错的计算机书籍(php c mysql linux等等)
推荐一些不错的计算机书籍. # PHP<PHP程序设计>(第2版) --PHP语法和入门最好的书<PHP5权威编程> --PHP入门后升级书<深入PHP:面向对象.模 ...
- qt 设置等待事件
QElapsedTimer et;et.start();while(et.elapsed() < 1000) QCoreApplication::processEvents();
- cocos2d-x iOS真机下载非根目录文件提示下载失败解决办法
在使用cocos api的Downloader或者AssetsManager下载文件到真机Document目录时,如果是直接下载到document根目录,是没问题的,如果是下载存放到了某个不存在的子目 ...
- Project Woosah Tu (五色土)
I bought this Raspberry Pi (model B) in spring 2013, I hadn't done too much with it except for some ...
- WebView返回时设置Title
private TextView mWebTitle; private com.tencent.smtt.sdk.WebView mX5Web; ......... if (mX5Web.canGoB ...