参考 动态生成类

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks; namespace ConsoleApplication1
{ public interface IGetData
{
void GetData(string name);
} public class GetDataFromDb : IGetData
{
public void GetData(string name)
{
Console.WriteLine( "Hello " + name);
}
} public class DynamicProxyBuilder
{
private static AssemblyBuilder DynamicAssembly;
private static ModuleBuilder ModuleBuilder; private static Dictionary<string, Type> TypeList = new Dictionary<string, Type>();
public static TTargetInterface GetProxyObject<TTargetInterface, TOriginalClass>() where TTargetInterface :class where TOriginalClass : TTargetInterface
{
Type target = typeof(TTargetInterface);
Type baseType = typeof(TOriginalClass);
CheckParams(target, baseType);
Type proxyType = AutoGenerateProxyClass(target, baseType);
var baseInstance = Activator.CreateInstance(baseType); return Activator.CreateInstance(proxyType, baseInstance ) as TTargetInterface;
} private static Type AutoGenerateProxyClass(Type target, Type baseType)
{
var proxyClassName = baseType.FullName + "Proxy";
if (!TypeList.ContainsKey(proxyClassName))
{
var module = GetDynamicModule();
var typeBuilder = module.DefineType(proxyClassName,
System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Class,
typeof(System.Object), new Type[] { target }); var fieldBuilder = typeBuilder.DefineField("OriginalObj", target, System.Reflection.FieldAttributes.Public);
CreateConstructorFunctionForType(baseType, typeBuilder, fieldBuilder);
foreach (var methodInfo in target.GetMethods())
{
CreateMethodForType(baseType, typeBuilder, methodInfo, fieldBuilder);
} TypeList.Add(proxyClassName, typeBuilder.CreateType());
} return TypeList[proxyClassName];
} private static void CreateConstructorFunctionForType(Type baseType, TypeBuilder typeBuilder, FieldBuilder fieldBuilder)
{
var objType = typeof(object);
ConstructorInfo objCtor = objType.GetConstructor(new Type[]);
ConstructorBuilder cb = typeBuilder.DefineConstructor(MethodAttributes.Public,
CallingConventions.Standard, new Type[] { baseType });
ILGenerator ilGenerator = cb.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
//先构建object的构造函数
ilGenerator.Emit(OpCodes.Call, objCtor);
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
//将本类的构建函数的参数赋值给本类的字段
ilGenerator.Emit(OpCodes.Stfld, fieldBuilder);
ilGenerator.Emit(OpCodes.Ret);
} private static void CreateMethodForType(Type baseType, TypeBuilder typeBuilder, MethodInfo method, FieldBuilder fieldBuilder)
{
var parameterInfos = method.GetParameters();
var paramTypes = new Type[parameterInfos.Length];
for (int i = ; i < parameterInfos.Length; i++)
{
paramTypes[i] = parameterInfos[i].ParameterType;
}
//准备好真正要调用的方法
var targetMethod = baseType.GetMethod(method.Name, paramTypes);
//创建代理方法,使用接口中相应方法的信息,并去掉期抽象方法属性
var methodBuilder = typeBuilder.DefineMethod(method.Name, method.Attributes & (~MethodAttributes.Abstract),
method.CallingConvention
, method.ReturnType, paramTypes); var il = methodBuilder.GetILGenerator();
il.EmitWriteLine("I am Proxyer");
//开始向栈中压参数,
//第1个参数 当前是this指针
il.Emit(OpCodes.Ldarg_0);
//压入当前引用的字段值 相当于 this.
il.Emit(OpCodes.Ldfld, fieldBuilder);
for (int i = ; i <= parameterInfos.Length; i++)
{
if (i == )
{ }
else if (i == )
{
il.Emit(OpCodes.Ldarg_1);
}
else if (i == )
{
il.Emit(OpCodes.Ldarg_2);
}
else if (i == )
{
il.Emit(OpCodes.Ldarg_3);
}
else
{
il.Emit(OpCodes.Ldarg_S);
}
} il.Emit(OpCodes.Callvirt, targetMethod);
il.EmitWriteLine("I done it!Bye!!");
il.Emit(OpCodes.Ret); } private static ModuleBuilder GetDynamicModule()
{
if (DynamicProxyBuilder.DynamicAssembly == null)
{
DynamicProxyBuilder.DynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynamicAssembly"),
AssemblyBuilderAccess.Run);
DynamicProxyBuilder.ModuleBuilder = DynamicProxyBuilder.DynamicAssembly.DefineDynamicModule("MainModule");
} return DynamicProxyBuilder.ModuleBuilder;
} private static void CheckParams(Type targetType, Type baseType)
{
if (!targetType.IsInterface)
throw new Exception("模板参数必须是接口");
}
} public class Program
{
static void Main(string[] args)
{
var instance = DynamicProxyBuilder.GetProxyObject<IGetData, GetDataFromDb>();
instance.GetData("Aven");
Console.Read();
}
}
}

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语言实战 逆序一个三位数

    题目:给定一个正的三位整数,比如123,输出321,但如果是700,输出必须是7不能是007 思路是怎么样的呢? 假设这个正三位数是m,它的百分位是c,十分位是b,个位是a,那么就存在下面的等式. m ...

  2. php连接redis

    $redis = new Redis(); $redis->connect();

  3. poj 1611 The Suspects(第一道并查集)

    题意: 有N个学生,编号为0-n-1,现在0号学生感染了非典,凡是和0在一个社团的人就会感染, 并且这些人如果还参加了别的社团,他所在的社团照样全部感染,社团个数为m,求感染的人数. 输入: n代表人 ...

  4. [GO]局部变量的特点

    package main import "fmt" func main() { //定义在{}里的变量就是局部变量,只能在{}里起作用 //作用域,变量起作用的范围 //执行到定义 ...

  5. 团队项目第六周-Alpha阶段项目复审(深海划水队)

    经小组讨论后得出以下排名: 队名 优点 缺点 排名 大猪蹄子队 界面优美,功能简洁易懂,单词解释较为完善 互动方式.操作简易性有待优化,有部分功能尚未完成 1 Running Duck队 基本功能已经 ...

  6. Microsoft.Office.Interop.Word.DocumentClass.SaveAs 命令失败

    asp.net 常用的生成word功能,代码也是网上常见的,自己本地反复测试过没问题.serves 2003下运行没问题,可是发布到2008上就出错.组件权限已配置,windows目录下temp权限已 ...

  7. 小度wifi在window server2008R2系统下创建不了

    小度wifi在window server2008R2系统下创建的时候会一直显示正在创建,然后又消失的情况.这是因为win server 2008下默认的无线lan服务没开启 解决方法: 在“服务管理器 ...

  8. c#设计模式之:组合模式(Composite)

    一:引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理,因为目录客园包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象和复合对象在功能上 ...

  9. 从头开始学eShopOnContainers——开发环境要求

    一.简介 eShopOnContainers是一个简化版的基于.NET Core和Docker等技术开发的面向微服务架构的参考应用,是一个简化版的在线商城/电子商务应用,其包含基于浏览器的Web应用. ...

  10. sqlServer DataReader与DataSet的区别

    sqlServer   DataReader与DataSet的区别 从以下这几个方面比较: 1.与数据库连接: DataReader:面向连接,只读,只进,只能向前读,读完数据就断开连接: DataS ...