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编程(三)之动态代理的更多相关文章

  1. ILGenerator.Emit动态 MSIL编程(一)之基础

    首先在Framework中,Emit相关的类基本都存在于System.Reflection.Emit命名空间下.可见Emit是作为反射的一个元素存在的. Emit能够实现什么?为什么要学习Emit?首 ...

  2. ILGenerator.Emit动态 MSIL编程(二)之基础

    public sealed class ColorToArgb { /// <summary> /// 将十六进制转化为AGRB /// </summary> /// < ...

  3. C# 使用Emit实现动态AOP框架 (三)

    目  录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...

  4. WIN 下的超动态菜单(三)代码

    WIN 下的超动态菜单(一)简介 WIN 下的超动态菜单(二)用法 WIN 下的超动态菜单(三)代码 作者:黄山松,发表于博客园:http://www.cnblogs.com/tomview/ 超动态 ...

  5. MyBatis学习 之 三、动态SQL语句

    目录(?)[-] 三动态SQL语句 selectKey 标签 if标签 if where 的条件判断 if set 的更新语句 if trim代替whereset标签 trim代替set choose ...

  6. 驱动里执行应用层代码之KeUserModeCallBack(WOW64是由三个动态库wow64.dll wow64win.dll wow64cpu.dll来实现)

    在驱动层(ring0)里执行应用层(ring3)代码,这是个老生常谈的技术,而且方法也挺多. 这种技术的本质:其实就是想方设法在驱动层里把应用层代码弄到应用层去执行. 比如在APC异步调用中,KeIn ...

  7. C#高级编程9-第12章 动态语言扩展

    C#高级编程9-第12章 动态语言扩展 dynamic t = new ExpandoObject(); t.Abc = "abc"; t.Value = ; Console.Wr ...

  8. 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 ...

  9. centos DNS服务搭建 DNS原理 使用bind搭建DNS服务器 配置DNS转发 配置主从 安装dig工具 DHCP dhclient 各种域名解析记录 mydns DNS动态更新 第三十节课

    centos  DNS服务搭建  DNS原理  使用bind搭建DNS服务器 配置DNS转发 配置主从  安装dig工具  DHCP  dhclient  各种域名解析记录  mydns DNS动态更 ...

随机推荐

  1. 366. Find Leaves of Binary Tree

    Given a binary tree, collect a tree's nodes as if you were doing this: Collect and remove all leaves ...

  2. 随感一:android handler传值更改ui

    handler+looper传值更改activity的UI 博客开了一段时间,一直想写点自己的学习经验及体会,等着以后长时间不用再要用到的时候直接拿过来上手.想了想,之前用到handler, 看了几篇 ...

  3. css中文乱码与替换字符

    有时候,我们的css样式表中字体乱码,很诧异.百度谷歌是两个老师,有时jquery博客还上淘宝,那边有现成的代码,看看,发现里面定义全局字体是这样的font:12px/1.5 tahoma,arial ...

  4. WordPress

    WordPress: 1.一种使用PHP语言开发的博客平台 2.用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站 3.也可以把 WordPress当作一个内容管理系统(CMS)来使用 ...

  5. BackTrack5-r3安装VMware Tools

    bt login:root //默认的BT系统账号password:toor //默认的BT系统密码,这里的密码是不显示的.root@bt:~#startx //进入图形模式 启动BT虚拟机系统-在V ...

  6. array_unshift() 、

    定义和用法 array_unshift() 函数在数组开头插入一个或多个元素. 被加上的元素作为一个整体添加,这些元素在数组中的顺序和在参数中的顺序一样. 该函数会返回数组中元素的个数. 语法 arr ...

  7. js去空格

    写成类的方法格式如下:(str.trim();) <script language="javascript"> String.prototype.trim=functi ...

  8. 利用html5的画布canvas进行图片压缩处理

    在网上找的代码,按自己的需求改了下,忘记在哪找的了.这里记着方便自己以后学习. // 参数,最大高度 //var MAX_HEIGHT = 100; var MAX_WIDTH = 200; // 渲 ...

  9. C++开发过程多线程同步lock的实现

    在程序开发过程经常使用到多线程,而多线程始终与锁存在紧密地联系,以下详细的介绍如何在C++程序开发过程中自定义锁的几种方法. 1. 下面给出一段代码展现如何通过Mutex实现锁的功能(window p ...

  10. Apache2 同源策略解决方案 - 配置 CORS

    什么是同源策略 现在的浏览器大多配有同源策略(Same-Origin Policy),具体表现如下: 浏览某一网站,例如 http://www.decembercafe.org/.这个网页中的 Aja ...