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. java语法基础

    Java的基本符号(token) Java的单词符号有五种:关键字.标识符.常量.分隔符和操作符. Java的字符集 Java 采用一种称为unicode的字符集,该字符集合是一种新的编码标准,与常见 ...

  2. 1.3 PROGRAM DEVELOPMENT ENVIRONMENT

    1.3 PROGRAM DEVELOPMENT ENVIRONMENT 1.4 WIN32 EXECUTEABLE FILE FORMAT We should also know that compl ...

  3. Linux学习之路—Linux目录配置

    所有内容来自鸟哥私房菜 FHS标准的重点在于规范每个特定的目录下应该要放置什么样子的数据而已.事实上,FHS针对目录树架构仅仅定义三层目录下面应该放置什么数据,分别是: /(root,根目录):与开机 ...

  4. linux学习笔记2-linux的常用命令

    第一篇博客:linux学习笔记1-ubuntu的安装与基本设置 之中,已经介绍了如何安装linux操作系统,以及一些基本的设置修改. 本篇博客主要介绍linux中的一些常用的终端命令 ======== ...

  5. GPU 加速NLP任务(Theano+CUDA)

    之前学习了CNN的相关知识,提到Yoon Kim(2014)的论文,利用CNN进行文本分类,虽然该CNN网络结构简单效果可观,但论文没有给出具体训练时间,这便值得进一步探讨. Yoon Kim代码:h ...

  6. C# 获取 oracle 存储过程的 返回值

    存储过程 CREATE OR REPLACE PROCEDURE ADMIN.INSERT_OBJ ( OBJEFIRT_parms IN NVARCHAR2, OBJEDATT_parms IN N ...

  7. 当padding,margin,top为百分比值,具体数值如何计算

    padding以及margin的四个方向设置值为百分数的时候,是以父元素的宽度为基数来进行计算. (为了保持横向和纵向方向上的margin/padding一致,但是其实也不是一定以父元素的宽度为参照物 ...

  8. Linux删除apt-get安装的软件

    我们都知道安装软件最简单的方法是apt-get install,但是卸载就不常用了,如何卸载呢?1.sudo apt-get remove xxxxxsudo apt-get autoremove2. ...

  9. 高效能人士必知铁律--note

    偶然看到了<高效能人士 必知铁律>这本书,我比较少看成功学,但是这本书把很多著名的成功学书籍整理出来,有时会让你耳目一新,有些观点尽管是常识,但是却加深了你对它们的理解,比如: 只要在积极 ...

  10. JSP学习流程