参考 动态生成类

http://www w2bc com/Article/44799

http://www.cnblogs.com/yingql/archive/2009/03/24/1420914.html

http://www.cnblogs.com/BangQ/archive/2011/07/19/2110301.html?spm=5176.100239.0.0.kAe2my

http://www.cnblogs.com/yuming1983/p/3701540.html

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Reflection.Emit;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8.  
  9. namespace ConsoleApplication1
  10. {
  11.  
  12. public interface IGetData
  13. {
  14. void GetData(string name);
  15. }
  16.  
  17. public class GetDataFromDb : IGetData
  18. {
  19. public void GetData(string name)
  20. {
  21. Console.WriteLine( "Hello " + name);
  22. }
  23. }
  24.  
  25. public class DynamicProxyBuilder
  26. {
  27. private static AssemblyBuilder DynamicAssembly;
  28. private static ModuleBuilder ModuleBuilder;
  29.  
  30. private static Dictionary<string, Type> TypeList = new Dictionary<string, Type>();
  31. public static TTargetInterface GetProxyObject<TTargetInterface, TOriginalClass>() where TTargetInterface :class where TOriginalClass : TTargetInterface
  32. {
  33. Type target = typeof(TTargetInterface);
  34. Type baseType = typeof(TOriginalClass);
  35. CheckParams(target, baseType);
  36. Type proxyType = AutoGenerateProxyClass(target, baseType);
  37. var baseInstance = Activator.CreateInstance(baseType);
  38.  
  39. return Activator.CreateInstance(proxyType, baseInstance ) as TTargetInterface;
  40. }
  41.  
  42. private static Type AutoGenerateProxyClass(Type target, Type baseType)
  43. {
  44. var proxyClassName = baseType.FullName + "Proxy";
  45. if (!TypeList.ContainsKey(proxyClassName))
  46. {
  47. var module = GetDynamicModule();
  48. var typeBuilder = module.DefineType(proxyClassName,
  49. System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Class,
  50. typeof(System.Object), new Type[] { target });
  51.  
  52. var fieldBuilder = typeBuilder.DefineField("OriginalObj", target, System.Reflection.FieldAttributes.Public);
  53. CreateConstructorFunctionForType(baseType, typeBuilder, fieldBuilder);
  54. foreach (var methodInfo in target.GetMethods())
  55. {
  56. CreateMethodForType(baseType, typeBuilder, methodInfo, fieldBuilder);
  57. }
  58.  
  59. TypeList.Add(proxyClassName, typeBuilder.CreateType());
  60. }
  61.  
  62. return TypeList[proxyClassName];
  63. }
  64.  
  65. private static void CreateConstructorFunctionForType(Type baseType, TypeBuilder typeBuilder, FieldBuilder fieldBuilder)
  66. {
  67. var objType = typeof(object);
  68. ConstructorInfo objCtor = objType.GetConstructor(new Type[]);
  69. ConstructorBuilder cb = typeBuilder.DefineConstructor(MethodAttributes.Public,
  70. CallingConventions.Standard, new Type[] { baseType });
  71. ILGenerator ilGenerator = cb.GetILGenerator();
  72. ilGenerator.Emit(OpCodes.Ldarg_0);
  73. //先构建object的构造函数
  74. ilGenerator.Emit(OpCodes.Call, objCtor);
  75. ilGenerator.Emit(OpCodes.Ldarg_0);
  76. ilGenerator.Emit(OpCodes.Ldarg_1);
  77. //将本类的构建函数的参数赋值给本类的字段
  78. ilGenerator.Emit(OpCodes.Stfld, fieldBuilder);
  79. ilGenerator.Emit(OpCodes.Ret);
  80. }
  81.  
  82. private static void CreateMethodForType(Type baseType, TypeBuilder typeBuilder, MethodInfo method, FieldBuilder fieldBuilder)
  83. {
  84. var parameterInfos = method.GetParameters();
  85. var paramTypes = new Type[parameterInfos.Length];
  86. for (int i = ; i < parameterInfos.Length; i++)
  87. {
  88. paramTypes[i] = parameterInfos[i].ParameterType;
  89. }
  90. //准备好真正要调用的方法
  91. var targetMethod = baseType.GetMethod(method.Name, paramTypes);
  92. //创建代理方法,使用接口中相应方法的信息,并去掉期抽象方法属性
  93. var methodBuilder = typeBuilder.DefineMethod(method.Name, method.Attributes & (~MethodAttributes.Abstract),
  94. method.CallingConvention
  95. , method.ReturnType, paramTypes);
  96.  
  97. var il = methodBuilder.GetILGenerator();
  98. il.EmitWriteLine("I am Proxyer");
  99. //开始向栈中压参数,
  100. //第1个参数 当前是this指针
  101. il.Emit(OpCodes.Ldarg_0);
  102. //压入当前引用的字段值 相当于 this.
  103. il.Emit(OpCodes.Ldfld, fieldBuilder);
  104. for (int i = ; i <= parameterInfos.Length; i++)
  105. {
  106. if (i == )
  107. {
  108.  
  109. }
  110. else if (i == )
  111. {
  112. il.Emit(OpCodes.Ldarg_1);
  113. }
  114. else if (i == )
  115. {
  116. il.Emit(OpCodes.Ldarg_2);
  117. }
  118. else if (i == )
  119. {
  120. il.Emit(OpCodes.Ldarg_3);
  121. }
  122. else
  123. {
  124. il.Emit(OpCodes.Ldarg_S);
  125. }
  126. }
  127.  
  128. il.Emit(OpCodes.Callvirt, targetMethod);
  129. il.EmitWriteLine("I done it!Bye!!");
  130. il.Emit(OpCodes.Ret);
  131.  
  132. }
  133.  
  134. private static ModuleBuilder GetDynamicModule()
  135. {
  136. if (DynamicProxyBuilder.DynamicAssembly == null)
  137. {
  138. DynamicProxyBuilder.DynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"),
  139. AssemblyBuilderAccess.Run);
  140. DynamicProxyBuilder.ModuleBuilder = DynamicProxyBuilder.DynamicAssembly.DefineDynamicModule("MainModule");
  141. }
  142.  
  143. return DynamicProxyBuilder.ModuleBuilder;
  144. }
  145.  
  146. private static void CheckParams(Type targetType, Type baseType)
  147. {
  148. if (!targetType.IsInterface)
  149. throw new Exception("模板参数必须是接口");
  150. }
  151. }
  152.  
  153. public class Program
  154. {
  155. static void Main(string[] args)
  156. {
  157. var instance = DynamicProxyBuilder.GetProxyObject<IGetData, GetDataFromDb>();
  158. instance.GetData("Aven");
  159. Console.Read();
  160. }
  161. }
  162. }

Emit生成特定接口的类的更多相关文章

  1. .net aop 操作 切面应用 Castle.Windsor框架 spring 可根据接口 自动生成一个空的实现接口的类

    通过unget 安装Castle.Windsor using Castle.DynamicProxy; using System; using System.Collections.Generic; ...

  2. 使用generatorConfig工具自动生成mybatis的实体类以及dao接口和映射文件

    1:数据准备 创建一个数据库表 CREATE TABLE `logininfo` ( `id` ) NOT NULL AUTO_INCREMENT, `username` ) DEFAULT NULL ...

  3. 2016.12.5 在Eclipse中为实现类impl自动生成对应接口

    参考来自:http://jingyan.baidu.com/article/ab69b270d63f572ca6189f51.html 在Spring应用中,常常会用到“接口+实现类”的形式,即要实现 ...

  4. 5.7 Liquibase:与具体数据库独立的追踪、管理和应用数据库Scheme变化的工具。-mybatis-generator将数据库表反向生成对应的实体类及基于mybatis的mapper接口和xml映射文件(类似代码生成器)

    一. liquibase 使用说明 功能概述:通过xml文件规范化维护数据库表结构及初始化数据. 1.配置不同环境下的数据库信息 (1)创建不同环境的数据库. (2)在resource/liquiba ...

  5. Servlet API遍程常用接口和类

    本文主要总结Servlet  API遍程常用接口和类 Servlet API http://tomcat.apache.org/tomcat-5.5-doc/servletapi/index.html ...

  6. (转)beanUtil接口和类(有空的时候去看,到时候删除这个说明)

    Jakarta Commons项目提供了相当丰富的API,我们之前了解到的Commons Lang只是众多API的比较核心的一小部分而已.Commons下面还有相当数量的子项目,用于解决各种各样不同方 ...

  7. BeanUtils接口和类

      Jakarta Commons项目提供了相当丰富的API,我们之前了解到的Commons Lang只是众多API的比较核心的一小部分而已.Commons下面还有相当数量的子项目,用于解决各种各样不 ...

  8. c#实例化继承类,必须对被继承类的程序集做引用 .net core Redis分布式缓存客户端实现逻辑分析及示例demo 数据库笔记之索引和事务 centos 7下安装python 3.6笔记 你大波哥~ C#开源框架(转载) JSON C# Class Generator ---由json字符串生成C#实体类的工具

    c#实例化继承类,必须对被继承类的程序集做引用   0x00 问题 类型“Model.NewModel”在未被引用的程序集中定义.必须添加对程序集“Model, Version=1.0.0.0, Cu ...

  9. Swagger+Spring mvc生成Restful接口文档

    简介 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集 ...

随机推荐

  1. C#实现访问网络共享文件夹

    C#实现访问网络共享文件夹,使用 WNetAddConnection2A 和 WNetCancelConnection2A. 在目标服务器建立共享文件夹,建立访问账号test; public enum ...

  2. c# 常规验证基类

    using System;using System.Collections.Generic;using System.Linq;using System.Text.RegularExpressions ...

  3. html5操作类名API——classlist

    tagNode.classList.add('123'); // 添加类 tagNode.classList.remove('bbb'); // 删除类 tagNode.classList.toggl ...

  4. Linux、Windows中的相对路径和绝对路径

    获取系统的分隔符的方式:System.getProperty("file.separator")   Windows为 \   Linux为/ Windows绝对路径: 以盘符开始 ...

  5. Java基础语法(二)<运算符>

    运算符: 下面的都是相关的练习: 1.键盘录入一个三位整数数,请分别获取该三位数上每一位的数值 import java.util.Scanner; public class Test02 { publ ...

  6. oracle数据库之数据插入、修改和删除

    作为一合格的测试人员对数据库的单表查询.多表查询.分组查询.子查询等等这些基本查询方法还是要会的.不然到企业中,容易被一些人鄙视,或者说如果数据库学不好,表查不明白,那么对自己能力来说也是一种侮辱,因 ...

  7. Codeforces 900C. Remove Extra One(暴力)

    You are given a permutation p of length n. Remove one element from permutation to make the number of ...

  8. 【C#】特性标签中的属性解释

    第一个为特性作用于类,或者接口(interface) 第二个为是否允许重叠定义,就是连续写两个特性标签 第三个为是否继承,当继承时候,除输出子类外,父类也将输出

  9. layui之弹出层--从父窗口传递数据到子窗口

    原文链接:https://blog.csdn.net/Code_shadow/article/details/80524633 var Index = layer.open({ title: &quo ...

  10. 21天学通C++学习笔记(三):变量和常量

    1. 简述 内存是一种临时存储器,也被称为随机存取存储器(RAM),所有的计算机.智能手机及其他可编程设备都包含微处理器和一定数量的内存,用地址来定位不同的存储区域,像编号一样. 硬盘可以永久的存储数 ...