C# Emit动态代理生成一个实体对象
/// <summary>
/// 使用Emit动态代理收集实体信息
/// </summary>
/// <typeparam name="T">实体类</typeparam>
public class TDynamicBuilder<T>
{
#region 变量区域
private static readonly MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item", new[] { typeof(int) }); private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull", new[] { typeof(int) }); private delegate T Load(IDataRecord dataRecord); /// <summary>
/// 代理
/// </summary>
private Load Handler;//最终执行动态方法的一个委托 参数是IDataRecord接口
#endregion #region 构造函数
private TDynamicBuilder() { }
#endregion #region +Build Emit动态代理生成一个实体对象
/// <summary>
/// Emit动态代理生成一个实体对象
/// </summary>
/// <param name="dataRecord">DataReader接口实现对象</param>
/// <returns></returns>
public T Build(IDataRecord dataRecord)
{
return Handler(dataRecord);//执行CreateBuilder里创建的DynamicCreate动态方法的委托
}
#endregion #region + CreateBuilder 创建一个Builder器
/// <summary>
/// 创建一个Builder器
/// </summary>
/// <param name="dataRecord">DataReader接口实现对象</param>
/// <returns></returns>
public static TDynamicBuilder<T> CreateBuilder(IDataRecord dataRecord)
{
var dynamicBuilder = new TDynamicBuilder<T>();
var type = typeof(T);
//定义一个名为DynamicCreate的动态方法,返回值typof(T),参数typeof(IDataRecord)
var method = new DynamicMethod("DynamicCreate", type, new[] { typeof(IDataRecord) }, typeof(T), true);
var generator = method.GetILGenerator();//创建一个MSIL生成器,为动态方法生成代码
var result = generator.DeclareLocal(type);//声明指定类型的局部变量 可以T t;这么理解
//The next piece of code instantiates the requested type of object and stores it in the local variable. 可以t=new T();这么理解
generator.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
generator.Emit(OpCodes.Stloc, result);
var propertys = type.GetProperties();
//数据集合
for (var i = ; i < dataRecord.FieldCount; i++)
{
//查找属性
var propertyInfo = propertys.FirstOrDefault(a => string.Equals(a.Name.ToLower(), dataRecord.GetName(i).ToLower()));
if (propertyInfo == null) continue;
if (!string.Equals(propertyInfo.Name, dataRecord.GetName(i), StringComparison.CurrentCultureIgnoreCase)) continue;
//根据列名取属性 原则上属性和列是一一对应的关系
var endIfLabel = generator.DefineLabel(); /*The code then loops through the fields in the data reader, finding matching properties on the type passed in.
* When a match is found, the code checks to see if the value from the data reader is null.
*/
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldc_I4, i);
//就知道这里要调用IsDBNull方法 如果IsDBNull==true contine
generator.Emit(OpCodes.Callvirt, isDBNullMethod);
generator.Emit(OpCodes.Brtrue, endIfLabel); /*If the value in the data reader is not null, the code sets the value on the object.*/
generator.Emit(OpCodes.Ldloc, result);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldc_I4, i);
generator.Emit(OpCodes.Callvirt, getValueMethod); //调用get_Item方法
generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i));
generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); //给该属性设置对应值 generator.MarkLabel(endIfLabel); } /*The last part of the code returns the value of the local variable*/
generator.Emit(OpCodes.Ldloc, result);
generator.Emit(OpCodes.Ret);//方法结束,返回 //完成动态方法的创建,并且创建执行该动态方法的委托,赋值到全局变量handler,handler在Build方法里Invoke
dynamicBuilder.Handler = (Load)method.CreateDelegate(typeof(Load));
return dynamicBuilder;
}
#endregion }
C# Emit动态代理生成一个实体对象的更多相关文章
- Java动态代理:一个面包店的动态代理帝国
文章首发于[博客园-陈树义],点击跳转到原文大白话说Java动态代理:一个面包店的动态代理帝国 代理模式是设计模式中非常重要的一种类型,而设计模式又是编程中非常重要的知识点,特别是在业务系统的重构中, ...
- Emit动态代理.NetCore迁移之旅
[前言] 前面我们介绍了Aop 从静态代理到动态代理:https://www.cnblogs.com/7tiny/p/9657451.html 我们在.NetFramework平台下使用微软提供的Em ...
- 通过模拟Mybatis动态代理生成Mapper代理类,讲解Mybatis核心原理
本文将通过模拟Mybatis动态代理生成Mapper代理类,讲解Mybatis原理 1.平常我们是如何使用Mapper的 先写一个简单的UserMapper,它包含一个全表查询的方法,代码如下 pub ...
- 获取动态代理生成的.class文件
生成代理类,并写入硬盘:配置系统属性sun.misc.ProxyGenerator.saveGeneratedFile为true,代理类生成时将自动将生成的代理类写入硬盘 ? 1 2 3 4 5 6 ...
- 【SpringCloud原理】万字剖析OpenFeign之FeignClient动态代理生成源码
年前的时候我发布两篇关于nacos源码的文章,一篇是聊一聊nacos是如何进行服务注册的,另一篇是一文带你看懂nacos是如何整合springcloud -- 注册中心篇.今天就继续接着剖析Sprin ...
- JAVA-获取 JDK 动态代理生成的 Class 文件
可指定路径 import sun.misc.ProxyGenerator; import java.io.FileOutputStream; import java.io.IOException; i ...
- 使用Netty和动态代理实现一个简单的RPC
RPC(remote procedure call)远程过程调用 RPC是为了在分布式应用中,两台主机的Java进程进行通信,当A主机调用B主机的方法时,过程简洁,就像是调用自己进程里的方法一样.RP ...
- 做一些Spring AOP做过的事,封装 jdk动态代理成为一个黑盒子
怎么使用eclise 抽取方法,请看 利用eclipse 抽取代码片段为方法 抽取完成之后,还需要 ① 将Collection.class换成 target.getClass(),targ ...
- console.log的一个应用 -----用new方法生成一个img对象和document.createElement方法创建一个img对象的区别
我用两种方法来生成img对象,第一种方法是用new方法,第二种方法是用document.createElement方法. var img1 = new Image(); var img2 = docu ...
随机推荐
- choorme 升级到最新版 adobe flash提示过期解决方案
进入adobe flash 官网,下载最新版的adobe flash http://labs.adobe.com/downloads/flashplayer.html
- Bzoj1455 罗马游戏
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1622 Solved: 679 Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人 ...
- struts2 Advanced Learning
catalog . 引言 . struts2的类型转换 . struts2的输入校验 . struts2的拦截器机制 . 使用struts2的Ajax支持 . struts2 OGNL表达式 . st ...
- mtd零星记录
查看Flash分区情况: root@DD-WRT:~# cat /proc/mtd dev: size erasesize name mtd0: "RedBoot" mtd1: 0 ...
- Response 对象
Response 对象用于将数据从服务器发送回浏览器. 页面跳转并传递参数 Response.Redirect("~/welcome.aspx?parameter1=one¶ ...
- vi编辑文件出现Can't open file for writing错误
可以用 ll 命令查看一下文件的权限,很有可能是没有权限,用chmod命令修改一下权限就可以了(当然是文件所有者或者root用户才能修改),或者切换成root用户(不推荐)
- Alpha版本十天冲刺——Day 2
站立式会议 会议总结 队员 今天完成 遇到的问题 明天要做 感想 鲍亮 学习post请求连接服务器,学习git 无 http资源请求方法封装,完成Android验证码获取接口和登录验证接口 今天满课, ...
- 【Alpha阶段】第二次Scrum例会
燃尽图软件存在bug,正在排查修复:(已修复)由于时区设置到了美国,图表显示有问题. 会议信息 时间:2016.10.18 22:00 时长:1h 地点:大运村1号公寓5楼楼道 类型:设计阶段阶段性会 ...
- 网络存储(四)之ISCSI的进阶
前言 上一篇博客中我们讲了如何搭建一个简单的iscsi网络存储系统,这块有个安全问题就是,任何知道target name的客户端都可以随意连接ISCSI服务器.但是很多时候,通过授权认证连接共享磁盘或 ...
- JavaWeb---总结(十八)JSP属性范围
所谓的属性范围就是一个属性设置之后,可以经过多少个其他页面后仍然可以访问的保存范围. 一.JSP属性范围 JSP中提供了四种属性范围,四种属性范围分别指以下四种: 当前页:一个属性只能在一个页面中取得 ...