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动态更 ...
随机推荐
- jquery 甘特图开发指南
JQuery.Gantt是一个开源的基于JQuery库的用于实现甘特图效果的可扩展功能的JS组件库. <link rel="stylesheet" href="cs ...
- NOIP 考前 图论练习
LJOJ 1500: 题目:http://www.docin.com/p-601990756.html Sol:贪心,从叶子结点往上加入无法传递了,就需要建设. Dfs返回的是到达叶子节点最多所要的能 ...
- Mac下搭建php开发环境【转】
Mac OS X 内置了Apache 和 PHP,这样使用起来非常方便.本文以Mac OS X 10.6.3为例.主要内容包括: 启动Apache 运行PHP 安装MySQL 使用phpMyAdmin ...
- 使用Spring 发送 Email !!!!
邮件服务器: 邮件服务器提供了邮件系统的基本结构,包括邮件传输,邮件分发,邮件存储等功能,以确保邮件能够发送到互联网中的任意地方. 邮件服务器就像我们生活中的邮局,为人们提供邮件服务.要保证邮件被正确 ...
- #import和@class的使用
#import #import 大部分功能和#include是一样的,但是他处理了重复引用的问题,不用再去自己进行重复引用处理. @class 用于声明一个类,告诉编 ...
- 使用自定的Adapter绑定ListView/GridView数据
使用自定的Adapter绑定ListView/GridView数据(地址) 对于ListView/Gridview的数据绑定, google提供了一些Adapter的模板, 自己也可以自定义一些个性化 ...
- git常见错误
一.如果输: $ git remote add origin git@github.com:djqiang(github帐号名)/gitdemo(项目名).git 提示出错信息:fat ...
- 收拾那掉了一地的session
多个页面有如下多个session,本来可能是如下面这样的 Session["UId"] = 10; Session["UName"] = "test& ...
- 可能是Mac环境变量恢复的参考
因为要做物联网实验的缘故,于是在Mac上用Android Studio想导入SensorSimulator的demo项目. 根据SensorSimulator的相关说明,需要先将Sensor Simu ...
- python27 windows 下三种安装第三方库的办法
一.使用easy_install C:\Python27\Scripts 下有 easy_install.exe .例如我要安装 beautifulsoup,可以从 cmd 进入该目录,直接运行: e ...