最近手头项目接触到了CodeDom,顺带着在这里做个系列文章,有兴趣的可以做个参考。

 
CodeDOM是个用于运行时生成代码,以及编译生成的代码的相关技术。我们通过构造CodeDOM这样的DOM树 来自动生成代码。
和反射都属于动态编程相关的技术。我们知道反射用的比较多的地方在于各种框架,在运行时创建实例以及相关操作。那CodeDOM有哪些用途呢?
MSDN---

CodeDOM 的一些一般用途包括:

  • 模板化代码生成:生成 ASP.NET、XML Web 服务客户端代理、代码向导、设计器或其他代码发出机制的代码。

  • 动态编译:支持以一种或多种语言进行代码编译。
     
    动态编译我们怕是没什么机会接触了,那就剩下第一种可能。第一种用途也说的很含糊,我们暂且不管,code起来再说。
    我们以一个简单的例子做解释
 class Program
{ //codedom 这种东西 是用来自动生成代码的,而生成什么样的代码就依靠我们提供的codeDom代码树,这个名词很类似于html Dom,也就是
//我们编好 codedom结构树,他会帮我们什么代码。(好像理所当然的感觉) 至于生成什么样的语言的代码,则要看所提供的不同的provider. static void Main(string[] args)
{ GenerateCode(); //先生成,这时候 文件已经生成了
CompilerResults results = CompileCode("generatedHelloWorld.cs"); //在编译我们生成的cs文件
Console.ReadKey();
} //构造dom树 创建编译单元.这一步是我们写代码的主体
public static CodeCompileUnit createCompileUnit()
{
CodeCompileUnit compileUnit = new CodeCompileUnit();
//开始构造最简单的代码树, 先把各个节点创建出来 再关联他们之间的关系。
//命名空间
CodeNamespace ns = new CodeNamespace("Demo");
//类名
CodeTypeDeclaration typename = new CodeTypeDeclaration("Test");
//定义一个main入口方法
CodeEntryPointMethod entry = new CodeEntryPointMethod();
//在main方法里面输出console.writeline(helloworld);
CodeMethodInvokeExpression expression_1 = new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression("System.Console"),
"WriteLine",
new CodePrimitiveExpression("Hello world! This is auto generated code ,Congratulations!")
);
//再输出一句console.readkey();
CodeMethodInvokeExpression expression_2 = new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression("System.Console"),
"ReadKey"
); //连接节点
compileUnit.Namespaces.Add(ns);
ns.Imports.Add(new CodeNamespaceImport("System"));
ns.Types.Add(typename);
typename.Members.Add(entry);
entry.Statements.Add(expression_1);
entry.Statements.Add(expression_2);
return compileUnit; } //重要的对象就是 generator compiler 以及parser
//根据创建的编译单元 生成代码
public static void GenerateCode()
{
//用于生成C#代码的provider
CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeGenerator generator = provider.CreateGenerator();
StreamWriter writer = new StreamWriter("generatedHelloWorld.cs",false);
generator.GenerateCodeFromCompileUnit(createCompileUnit(),writer,new CodeGeneratorOptions());
writer.Close();
} //编译自动生成的源码
public static CompilerResults CompileCode(string filepath)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeCompiler compiler = provider.CreateCompiler();
//我们还需要提供一些编译所需要的参数
CompilerParameters paras = new CompilerParameters(new string[]{"System.dll"},"HelloWorld.exe",false);
paras.GenerateExecutable = true;
CompilerResults results = compiler.CompileAssemblyFromFile(paras,filepath);
return results;
}
}

步骤其实并不复杂,就是 拼接compileUnit树, 根据树生成.cs文件,编译生成的文件。在运行我们上面的程序之后 发现,文件夹多了一些东西

就是我们生成的文件,运行HelloWorld.exe

很开森有木有!看来和CodeDom初识还是愉悦的~

CodeDOM 系列一: 初识的更多相关文章

  1. WCF编程系列(一)初识WCF

    WCF编程系列(一)初识WCF   Windows Communication Foundation(WCF)是微软为构建面向服务的应用程序所提供的统一编程模型.WCF的基本概念:  地址:定义服务的 ...

  2. Gradle系列之初识Gradle

    原文首发于微信公众号:躬行之(jzman-blog) 学习 Android 有一段时间了,开发中经常使用到 Gradle ,但是不知道 Gradle 构建项目的原理,计划花一点时间学习一下 Gradl ...

  3. .net core系列之初识asp.net core

    .net core已经发布了2.0版本,相对于1.0的有了很大的完善,最近准备在项目中尝试使用asp.net core,所以就进行了一些简单的研究. 初识asp.net core分为以下几个部分: 1 ...

  4. SpringMVC 框架系列之初识与入门实例

    微信公众号:compassblog 欢迎关注.转发,互相学习,共同进步! 有任何问题,请后台留言联系! 1.SpringMVC 概述 (1). MVC:Model-View-Control Contr ...

  5. 【安卓网络请求开源框架Volley源码解析系列】初识Volley及其基本用法

    在安卓中当涉及到网络请求时,我们通常使用的是HttpUrlConnection与HttpClient这两个类,网络请求一般是比较耗时,因此我们通常会在一个线程中来使用,但是在线程中使用这两个类时就要考 ...

  6. Node.js实战项目学习系列(1) 初识Node.js

    前言 一直想好好学习node.js都是半途而废的状态,这次沉下心来,想好好的学习下node.js.打算写一个系列的文章大概10几篇文章,会一直以实际案例作为贯穿的学习. 什么是node Node.js ...

  7. Vue.js系列之一初识Vue

    在看vue.js之前,可以先看这两篇文章,对于为什么要使用vue会有一定帮助 1.Vue.js !important 2.界面之下:还原真实的MV*模式 !important 3.web前端优化之re ...

  8. MySql系列之初识

    数据库管理软件的由来 基于我们之前所学,数据要想永久保存,都是保存于文件中,毫无疑问,一个文件仅仅只能存在于某一台机器上. 如果我们暂且忽略直接基于文件来存取数据的效率问题,并且假设程序所有的组件都运 ...

  9. Spring系列之初识Spring Spring概述

    初始Spring 啥是Spring? 下面这个就是Spring Spring当然不是上面那个Spring,Spring之所以命名为Spring是因为这个开源的轻量级的开源框架的出现给软件行业带来了春天 ...

随机推荐

  1. HTML textares的使用

    <textarea>标签定义及用法 在html中,<textarea>标签是用来定义一个多行的文本输入控件,在文本输入域中可以输入任意长度的文本.文本默认字体是等宽字体(Cou ...

  2. ubuntu下nodejs源码安装

    1.从github选择下载自己要安装的nodejs版本,https://github.com/nodejs/node/releases,我下载的版本是node-9.11.2.tar.gz 2.解压no ...

  3. mongoose 基础api 图表整理

    一.背景 今天看 mongoose 的基础 API,参考了下面的链接做了图表以供查阅. 参考资料: http://www.cnblogs.com/xiaohuochai/p/7215067.html ...

  4. linux源码安装的步骤

    源码安装的过程中多多少少会遇到问题,在此仅简述一下安装的步骤,具体安装的过程中遇到的问题,具体解决. 安装步骤: 1.获取源码 name.gz 2.解包 tar -xvf name.gz (cd到包解 ...

  5. python爬虫在解析不带引号的json报错的问题解决方案

    本例中环境: python3.6.6 demjson-2.2.4 如不看废话请直接看3(下面红体字) 1.近期在爬取代理验证代理的时候发生一个Bug, 就是在验证代理的时候返回的是如下字符串, {ip ...

  6. 课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 1、10个测验题(Neural Network Basics)

    --------------------------------------------------中文翻译---------------------------------------------- ...

  7. Ruby:线程实现经典的生产者消费者问题

    运行结果: ProAndCon 0 produced 1 produced consumed 0 2 produced 3 produced consumed 1 consumed 2 consume ...

  8. SSDT Hook实现内核级的进程保护

    目录 SSDT Hook效果图 SSDT简介 SSDT结构 SSDT HOOK原理 Hook前准备 如何获得SSDT中函数的地址呢 SSDT Hook流程 SSDT Hook实现进程保护 Ring3与 ...

  9. Git for Windows之基础环境搭建与基础操作

    一.安装Git工具 下载地址:Git For Windows 下载完后,安装,全程Next. 二.全局配置 1.配置本地用户名,用于提交代码 2.配置邮箱 三.创建本地Git项目仓库 1.建立代码仓库 ...

  10. linux内核学习之全局描述符表(GDT)(二)

    来源:https://www.cnblogs.com/longintchar/p/5224406.html 在进入保护模式之前,我们先要学习一些基础知识.今天我们看一下全局描述符表(Global De ...