zoukankan      html  css  js  c++  java
  • 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);//编译程序集
            }

        }
    }
    结果截图:
    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


    作者:破  狼
    出处:http://www.cnblogs.com/whitewolf/
    本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼

  • 相关阅读:
    C++ 内置函数 判断字母、数字及大小写转换
    C++11 随机数 random
    rpc
    C++11 智能指针
    xargs 命令使用
    记录优秀的文章
    腾讯 测试开发
    struts2文件上传、下载、防止重复提交
    注解
    @RestController注解
  • 原文地址:https://www.cnblogs.com/whitewolf/p/1760708.html
Copyright © 2011-2022 走看看