浅尝辄止:通过DynamicMethod和ILGenerator创建实体类

周末尝试着学习emit进行高级编程。想起若干天前收藏的 Herbrandson 在codeproject上的 神作 (此文技术含量其实一般,实际上他讲的就是用 DynamicMethod ILGenerator 实现快速实体创建的方法,但是文笔睿智,用词精致,非常诱人),重温了一下原文,又参考了msdn和园子里几位高手的博客,整理一下自己的学习笔记,希望对您有用。

一、常见的将DataReader转换为List的方法
1、类似codesmith的模板生成方式
熟悉代码生成器的童鞋一定知道的。在实体类里生成了“一堆”字段,属性,数据类型等等相关的判断(不是switch...case就是if...else等等等等)。其实也就类似Herbranson原文里介绍的第一种实现方式。毫无疑问,这种方式简单直接明了,是个程序员都看得懂,但是多数人会嫌弃代码啰嗦,生成的类会显得非常臃肿庞大。
代码

2、反射,反射,兴高采烈地登场
大家都觉得上面第一种的实现代码毫无美感,通过反射,世界就清静多了:

代码

观察上面的代码,大家会发现程序的通用性大大增强,减少了大量重复的工作,技术含量也是杠杠的。
ps:前面两种方式的实现代码都是原文里拷贝来的。大家最常见的就是这两种方式,所以懒得写注释了,没什么难度的。
ps1:通过反射转换实体,其实还有其他写法的,但是主要思想大同小异(厚颜推荐楼猪的关于ado.net的旧文)。

二、来一点点emit,性能提高不是一点点
这就是传说已久的通过emit创建动态代理,实现实体的创建:

代码

(1)、因为老外的这个实现方式涉及到emit的知识,大部分开发者可能了解的并不是很深入,楼猪也不是很熟悉,而且楼猪极不习惯emit这种编程风格,感觉它非常破坏代码的美感,这种牺牲色相的高级写法如果在我们的项目中大面积出现,估计大部分童鞋都会抓狂的。好在现在终于有了工具可以“Emit with a human face”了。
(2)、不管怎样,还是凭借自己学习到的一点知识储备,大胆按照自己的理解,写了点注释,对照原文作者的意思,不见得很烂,就是这么自信,呵呵。
在外部调用的方式如下(测试代码,无比丑陋,请留意):

代码

需要说明的是,生成实体的时候,while(rdr.Read())必须判断,原文里没有提及。

三、改进ado.net快速上手里的DataReader转换成实体对象
楼猪在旧文里曾经写了个数据转换类(ModelConverter),现在放弃反射的方式,采用Herbrandson介绍的动态代理实现数据实体的创建:

代码

DynamicBuilder类就是上面介绍的通过DynamicMethod和ILGenerator的方式。这样,QueryForList和QueryForDictionary方法的性能就得到了改善。
需要说明的是,在实体转换的时候,QueryForDictionary方法的字典的key的获取是通过BuildPrimaryKey泛型方法,直接从IDataReader里取值,而没有通过emit生成动态代理获取(有心的童鞋可以小试牛刀,看看如何通过构建动态代理获取key),个人认为使用emit适可而止,没必要矫枉过正。

先写到这里了。你还在纠结要不要学习emit? Yes,it works.








本文转自JeffWong博客园博客,原文链接:http://www.cnblogs.com/jeffwongishandsome/archive/2010/08/01/1790057.html,如需转载请自行联系原作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值