.Net开发笔记(八) 动态编译

简介:

虽然标题为“动态编译”,其实本文包含两个部分,一个就是标题说的动态编译源代码,另外一个应该是动态生成源代码。也就是说,在.Net中可以存在这样一种情况:在程序运行期间,由程序控制动态生成一份源代码(Source Code),然后再编译该源代码,生成一个新的程序集,紧接着再加载生成的程序集,最后运行。这个情况可能出现在很多地方,比如一些模板代码生成,像asp.net页面生成html,还可以在程序运行期间,由用户控制,动态的扩展程序功能。

要了解以上的实现过程,需先了解以下几个知识点:

  1. 反射
  2. 跨应用程序域(AppDomain)访问支持
  3. CodeDOM(代码文档对象模型)

我大概介绍一下后面两个,反射我就不说什么了,想必诸位都清楚,文章最后我会展示一下我做的一个Demo,主要有两个功能,动态编译代码和仿aspx页面生成html,功能很简单做工也很粗糙,但大概的原理过程都有,提供原程序下载,源程序注释都很详细,下下来就能看懂。

AppDomain(应用程序域):

先引用MSDN上的一句话:应用程序域(由 AppDomain 对象表示)为执行托管代码提供隔离、卸载和安全边界。是个什么意思呢?说得概括直白一点,就是它相当于一个容器,存放一些数据和其他资源,每个AppDomain都有自己的范围,各管各的事情,我们在将源代码(Source Code)动态编译成程序集后,还需要把它加载,最后运行,不然的话,动态编译就没什么意义了,想必各位清楚,在咱们学习“反射”的时候就知道用Assembly.Load()类似这样的方法加载程序集,然后创建实例(Instance),然后取得它的Type进行操作等等,但是如果按以上这样的方法加载的程序集的话,它默认被加载到当前AppDomain中(此当前AppDomain就是指程序一开始运行系统自动为其创建的一个AppDomain),又由于程序集不能单独卸载,也就是说加载进来之后的程序集会一直存在该AppDomain中,你如果加载的次数不多,这也就无所谓,但是如果像我们今天遇到的情况,需要反复不停的编译源代码,将生成的程序集加载运行的话,问题就出现了,最后加载进来的程序集就会越来越多,最后内存不足(Leak Memory),解决的办法就是,将每次用完的程序集卸载掉,目前卸载程序集的办法只有(我了解到的)卸载程序集所在的AppDomain,容器玩完了,容器里面的东西肯定也玩完了,但程序集如果一开始就加载到当前AppDomain中的话,问题就来了,因为当前AppDomain是不能被卸载的(如果当前AppDomain卸载了,什么都玩完了,怎么会有后续),所以,一开始加载程序集的时候,就不应该将其加载到当前AppDomain,这就需要我们新创建一个AppDomain,专门用来存放加载进来的程序集,一旦使用完毕后,马上将其卸载。创建新的AppDomain、跨域访问等具体操作,请看源代码。

CodeDOM(代码文档对象模型):

如果诸位知道DOM的话,这个其实很好理解,它两意思差不多,我们在处理html代码(XML)的时候,将它的各个节点都当做一个“对象”(Object),<Body></Body>、<Title></Title>等等,都是对象,在构建一个html文档的时候,我们可以先创建根,然后创建它的各个子节点,再然后设置各个子节点的属性、文本什么的,打个比方:HtmlHTML html = new HtmlHTML();HtmlHEAD head = new HtmlHead(); html.Childs.Add(head);创建两个节点对象,将一个加入到另外一个的子节点中去。.Net中System.Xml命名空间中有很多操作XML的类型,比如XmlAttribute、XmlElement、XmlComment等等,每一个类都代表XML文档中的一个节点元素,构建一个xml文档的时候,也是将一个加到另外一个的子节点集合中去,然后设置各个元素的其他属性等等,大概操作基本都这样。网上摘抄一段代码如下:

View Code

如上所述,构建一个xml文档的代码。那么,CodeDOM就可以类比了,把什么命名空间(namespace)、类(Class)、引用(using)、方法(Method)、事件(Event)、赋值语句(AssignStatement)、异常捕获(TryCatchFinallyStatement)等等都当做对象,如果你仔细观察,发现其实程序源代码(Source Code)的结构跟html、xml等都是一样一样的,一层嵌套着另外一层,既然一样,那么我们构造一个源程序文档的方法肯定也是和构造DOM结构文档一样。

另外,像XmlAttribute、XmlComment、XmlNode这样的类型存在System.Xml命名空间中,那么CodeDOM中的各个类型存在哪儿呢?.Net中为我们提供的这些类型在System.CodeDOM这个命名空间中,基本上源程序中各个结构都能在这个命名空间中找到对应的类型。

到此,我们知道了利用System.CodeDOM中的类型动态的构造源代码,那么怎么将构造完的源代码保存下来(生成文本格式的代码,保存成源文件)?以及怎么将其编译,生成最终可以运行的程序集?.Net中又为我们提供了专门用于生成源代码和编译源代码的类,它们存在System.CodeDOM.Compiler命名空间中,具体要使用其中的两个接口ICodeCompiler和ICodeGenerator,它们两个的C#和VB版的具体实现类存在Microsoft.CSharp命名空间和Microsoft.VisualBasic命名空间。生成源代码和编译源代码操作都会返回执行结果,可以在返回结果中查看相关信息,比如编译源代码时,可以查看编译错误。

现在我们已经清楚了整个流程,来张图说明一下:

图1

做的一个Demo

做的这个Demo中其实并没有使用到上图中的第2步和第3步,因为不需要动态生成源码,取而代之的是让用户直接输入源码,然后将输入的源码拿来编译执行,或者先将aspx页面代码(html和C#的混合体)解析成代码片段,然后拿来编译执行。也就是说,Demo中的流程应该是这样的:

图2

源码注释很详细,我就在这不贴了。再来两张效果图:

图3

图4

图5

源码C#部分XP .net3.5测试通过,VB部分没测试。

下载地址:http://download.csdn.net/detail/xiaozhi_5638/5172507

希望有帮助O(∩_∩)O~,如果觉得本文对您有用,请点击一下右下方的“赞”或者给个评论建议,非常感谢!!!

题外话:

    昨晚上跟b哥谈论一件衣服,一起回忆起了我大学时期的着装,无袖T恤+长短裤+ 人字拖,现在想想,甚是现世,不知不觉惭愧起来,责备自己年少不懂事,乱了校 规伤了风化。高三时,穿过一段时间的木屐+大裤衩,不知wy君是否还记得起?自认为学生时代没有给老师留下好的印象,学习成绩即不很突出,也不是老师眼中的乖乖娃,高中上语文时看物理,上物理课时看英语,被老师发现无数次,没办法,后来我一跟别人说我是偏科生,问哪科,答曰数学,无比脸红,丢尽了无数理科生的 脸,后来高考马马虎虎,读了一个二流大学,大一规规矩矩,大二开始翘课抄作业 ,即影响校容也丢了现代青年应有的颜面,谈来惭愧,不提也罢。有时候在讲一个 人过去是怎么“作恶多端”,并不是想衬托TA现在有多大进步,或者炫耀TA有一个 多么“拉风”的青春,这就像现在许多人讲自己出生如何贫寒,起跑线比别人多么 靠后,条件如何艰苦,但TA还是一直会坚持下去,他相信自己是个潜力股,说到这,无比骄傲,其实殊不知,出生贫寒并不是优势,起跑线落后更不是资本, 你说你是“潜力股”,吁,“潜力股”好多时候也许只是安慰那些有着弱小心灵的屌丝,不是吗,跑题了。其实我本人倒是一直推崇做事做完了就完了,不要总是回过头 去想它对不对,更要避免耿耿于怀,但学生时代的所作所为,有时候的确让我不安 ,觉得愧对各位老师,也许他们根本记不起,但还是在此道个不是,虽然我现在并 不是老师,也没有身兼“传道授业解惑者”这样的职业。《单车》中有句歌词“经 已给我怎会看不到,虽说演你角色实在有难度”,虽然角色不同,意义大概一样吧 。

作者:周见智 
出处:http://www.cnblogs.com/xiaozhi_5638/ 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

标签:  c#Winform

本文转自周见智博客博客园博客,原文链接:http://www.cnblogs.com/xiaozhi_5638/archive/2013/03/23/2976887.html,如需转载请自行联系原作者
目录
相关文章
|
23天前
|
Linux API C#
基于 .NET 开发的多功能流媒体管理控制平台
基于 .NET 开发的多功能流媒体管理控制平台
39 9
|
25天前
|
缓存 算法 安全
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
64 12
|
23天前
|
Web App开发 前端开发 调度
一款基于 .NET + Blazor 开发的智能访客管理系统
一款基于 .NET + Blazor 开发的智能访客管理系统
|
24天前
|
前端开发 JavaScript C#
基于.NET8+Vue3开发的权限管理&个人博客系统
基于.NET8+Vue3开发的权限管理&个人博客系统
|
24天前
|
网络协议 C#
基于.NET WinForm开发的一款硬件及协议通讯工具
基于.NET WinForm开发的一款硬件及协议通讯工具
|
24天前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
|
2月前
|
传感器 人工智能 供应链
.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。
本文深入探讨了.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。通过企业级应用、Web应用及移动应用的创新案例,展示了.NET在各领域的广泛应用和巨大潜力。展望未来,.NET将与新兴技术深度融合,拓展跨平台开发,推动云原生应用发展,持续创新。
51 4
|
Android开发
.Net 转战 Android 4.4 日常笔记目录
原文:.Net 转战 Android 4.4 日常笔记目录 .Net 转战 Android 4.4 日常笔记(1)--工具及环境搭建 .Net 转战 Android 4.4 日常笔记(2)--HelloWorld入门程序 .
836 0
|
4月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
57 7
|
4月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
103 0

热门文章

最新文章