zoukankan      html  css  js  c++  java
  • CodeDom系列1

    CodeDom系列-开篇HelloWord

    最近在自己实践一个异常扑捉设计,在模块中我觉得该给用户提供的是代码生成工具,而不是怎么去做,再自己去写代码。现在代码模板生成的有很多

    但我选择了用微软的CODEDOM技术来实现,由于比较熟悉,以及感觉我将只用在.NET平台是已经够强大了。最近也总想写点博客,但是不知道写些什么,所以就准备写个CODEDOM的系列。仅是开篇,就写个简单的HelloWord程序吧。

    CODEDOM在.NET Framework SDK文档里是这么讲述的:

    .NET Framework 中包含一个名为“代码文档对象模型”(CodeDOM) 的机制,该机制使编写源代码的程序的开发人员可以在运行时,根据表示所呈现代码的单一模型,用多种编程语言生成源代码。

    为表示源代码,CodeDOM 元素相互链接以形成一个数据结构(称为 CodeDOM 图),它以某种源代码的结构为模型。

    System.CodeDom 命名空间定义可以表示源代码的逻辑结构(与具体的编程语言无关)的类型。System.CodeDom.Compiler 命名空间定义从 CodeDOM 图生成源代码的类型,和在受支持的语言中管理源代码编译的类型。编译器供应商或开发人员可以扩展受支持语言的集合。

    还是先贴上代码:

    using System;
    using System.Text;
    using System.CodeDom;
    using System.CodeDom.Compiler;

    namespace CodeDomDemo1
    {
        
    class Program
        {
            
    static void Main(string[] args)
            {
                Program pro 
    = new Program();
                CodeNamespace nspace 
    = pro.CreateCodeDomHelloDemo();
                Console.WriteLine(pro.GengerCode(nspace));
                
    string filename = "HelloWorld.exe";
                CompilerResults result
    = pro.Execute(nspace,filename);
                
    if (result.Errors.HasErrors)//是否存在错误;
                {
                    
    for (int i = 0; i < result.Output.Count; i++)

                        Console.WriteLine(result.Output[i]);

                    
    for (int i = 0; i < result.Errors.Count; i++)

                        Console.WriteLine(i.ToString() 
    + "" + result.Errors[i].ToString());
                }
                
    else
                {
                    System.Diagnostics.Process.Start(filename);
    //这里比较懒,不想动手去自己打开,呵呵;
                }
                Console.Read();
            }

            
    public CodeNamespace CreateCodeDomHelloDemo()
            {
                CodeMemberMethod method 
    = new CodeMemberMethod();//方法声明; 
                method.Name = "SayHello";//  方法名
                method.Attributes = MemberAttributes.Public| MemberAttributes.Final;//属性
                method.ReturnType = new CodeTypeReference(typeof(string));//返回类型
                method.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression("Hello  from code!")));//方法体,只有一句返回语句return "Hello  from code!";

                CodeEntryPointMethod main 
    = new CodeEntryPointMethod();//主方法Main
                main.Statements.Add(new CodeVariableDeclarationStatement("HelloWord","hw",
                    
    new CodeObjectCreateExpression("HelloWord"new CodeExpression[] { })));//变量声明:HelloWord hw = new HelloWord();

             CodeMethodInvokeExpression methodinvoke
    =   new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("hw"),"SayHello",new CodeExpression[]{});
                main.Statements.Add(
    new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),"WriteLine", methodinvoke));
                main.Statements.Add(
    new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"), "Read"));//两个方法调用:System.Console.WriteLine(hw.SayHello());
               
                CodeTypeDeclaration helloword 
    = new CodeTypeDeclaration("HelloWord");//类型Class声明
                helloword.Attributes = MemberAttributes.Public;
                helloword.Members.AddRange(
    new CodeTypeMember[]{method,main});//添加方法到clss

                CodeNamespace nspace 
    = new CodeNamespace("HelloDemo1");//命名空间声明
                nspace.Imports.Add(new CodeNamespaceImport("System"));//引入程序命名空间:using System;
                nspace.Types.Add(helloword);//
                return nspace;
            }

            
    public string GengerCode(CodeNamespace nspace)
            {
                StringBuilder sb 
    = new StringBuilder();
                System.IO.StringWriter sw 
    = new System.IO.StringWriter(sb);
                CodeGeneratorOptions geneOptions 
    = new CodeGeneratorOptions();//代码生成选项

                    geneOptions.BlankLinesBetweenMembers 
    = false;

                    geneOptions.BracingStyle 
    = "C";

                    geneOptions.ElseOnClosing 
    = true;

                    geneOptions.IndentString 
    = "    ";
                    CodeDomProvider.GetCompilerInfo(
    "c#").CreateProvider().GenerateCodeFromNamespace(nspace, sw, geneOptions);//代码生成
                    sw.Close();
                    
    return sb.ToString();

            }

            
    public CompilerResults Execute(CodeNamespace nspace, string filename)
            {
                CodeCompileUnit unit
    =new CodeCompileUnit();//code编译单元
                unit.Namespaces.Add(nspace);
               CodeDomProvider provider
    =  CodeDomProvider.CreateProvider("C#");  
                CompilerParameters options
    =new CompilerParameters();//
               
                options.GenerateInMemory 
    =false;//是否在内存中生成;
                 options.IncludeDebugInformation =true;// 包含调试信息;
                options.ReferencedAssemblies.Add("System.dll");
                options.OutputAssembly 
    = filename;
                
    if (System.IO.Path.GetExtension(filename).ToLower() == ".exe")
                {
                    options.GenerateExecutable 
    = true;//true为可执行exe,false:dll
                }
                
    else
                {
                    options.GenerateExecutable 
    = false;//true为可执行exe,false:dll
                }
               
    return  provider.CompileAssemblyFromDom(options, unit);//编译程序集
            }

        }
    }
    4 结果截图:
    4 1:生成的代码:
    image

    2:运行结果:

    image 

    上面代码很简单,我特意也把注释写上了,所以不用一句一句的讲解了,哈哈。

    CodeDom提供了很多操作,如定义类,还可以定义结构、枚举;类里面的方法、属性、字段及构造函数;定义Attribute;事件及委托;赋值、条件(if)、循环(for)语句;变量声明;异常处理语句;甚至还可以加注释以及块(#region #endregion)。除了分支选择switch、while,dowhile循环及break、continue没发现外,其他大多数东西都有,着已经足够了,程序三大结构,足以实现很多的代码生成了。

    msdn CodeDom参考:http://msdn.microsoft.com/zh-cn/library/f1dfsbhc(VS.80).aspx

  • 相关阅读:
    PL/SQL 自动补全[转]
    关闭开发环境的开发者模式
    删除带外键的表【foreign key constraint fails】报错
    CSSS选择器总结
    XSS漏洞初窥(通过dvwa平台进测试)
    Oracle 闪回 找回数据
    Oracle 函数 Function
    Oracle 存储过程 PROCEDURE
    Oracle 备份与恢复
    Web应用程序架构的比较
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1760807.html
Copyright © 2011-2022 走看看