zoukankan      html  css  js  c++  java
  • CodeDOM 系列一: 初识

    最近手头项目接触到了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初识还是愉悦的~

  • 相关阅读:
    细说:Http协议 篇
    连接池
    实践
    事务
    一、Jdbc 入门
    ES6之路第一篇:let、const
    vue2饿了吗之路第二篇:登录
    RabbitMQ(三)——简单模式
    RabbitMQ(二)——模式类型
    RabbitMQ(一)——简介
  • 原文地址:https://www.cnblogs.com/JasonShenW/p/5288360.html
Copyright © 2011-2022 走看看