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:生成的代码:

2:运行结果:

 

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

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--破狼。http://www.cnblogs.com/whitewolf/archive/2010/06/19/1760708.html

时间: 2024-10-24 12:04:26

CodeDom系列-开篇HelloWord的相关文章

CodeDom系列目录

      CodeDOM 提供了表示许多常见的源代码元素类型的类型.您可以设计一个生成源代码模型的程序,使用 CodeDOM 元素  构成一个对象图.可以使用受支持的编程语言的 CodeDOM 代码生成器,将该对象图呈现为源代码.CodeDOM 也可以用于将  源代码编译成二进制程序集. CodeDOM 的一些一般用途包括: 模板化代码生成:生成 ASP.NET.XML Web 服务客户端代理.代码向导.设计器或其他代码发出机制的代码. 动态编译:支持以一种或多种语言进行代码编译. 经过连续几

Windows 8实例教程系列 - 开篇

原文:Windows 8实例教程系列 - 开篇   2012年10月26日,微软发布Windows 8操作系统以及自主品牌平板电脑Surface,Windows作为世界上最流行的操作系统,发布一周内,下载量超过400万.毋庸置疑 Windows Store正在酝酿着巨大的Windows应用市场,越来越多的应用开发商,互联网运营商,外包开发团队以及个人承包商加入到 Windows Store应用开发行列,相信未来几个月Windows Store应用数量将突飞猛进. 为了帮助更多开发人员学习和了解W

淘宝API开发系列--开篇概述

前阵子有空发现淘宝的API挺有意思的,就留意学习了一下,淘宝从2008.6月开始公测以来,API渐趋稳定,文档的相关说明也比较细致,不过基于淘宝API做应用的软件目前应该还不是很多,不过由于马云的影响力,淘宝API终会发光发热,给我们做开发的程序员多一份选择,多一个摆弄的东西. 在学习中,发现有一些比较好玩,比较有趣的地方,如果有空继续的话,准备开一个系列,总结介绍一下相关的知识,希望能够给博客多一份人气,多一份积累. 淘宝开放平台(Taobao Open Plateform,又叫TOP),地址

CodeDom系列五--动态编译

        继上节我们把Code 表达式编译成为了Code代码,有时我们只想动态编译程序集,在内存中或者是 硬盘上调用,这就是CodeDom的动态编译.微软在CodeDom中提供了动态编译程序,这是ICodeComp iler的用武之地了,它定义用于调用源代码编译的接口或使用指定编译器的 CodeDOM 树.可以从CodeDomProvider生成引用对象:CodeDomProvider.CreateProvider("").CreateCompiler();       在ICo

CodeDom系列二---程序基本结构--符号三角形问题

    昨天一个同学叫我帮编写一个符号三角形的c代码,今天就把它改写成用CodeDom生成的c#代码.     符号三角形:在一组字符串里(只有用空格分割的+或者-组成的字符串),在每次的相邻的两个符号比较,如果相同就在中间空格插入+,否则就插入-.一直运行到字符串里只有一个+或者-时停止,输出的字符串为符号三角形. 由于是CodeDom些列,所以先介绍几个CodeDom表达式: 1:CodeConditionStatement:判断语句即是if(condition){} else{},看最全的

CodeDom系列四--Code生成

      我们利用CodeDom技术生成了一些列Codedom Expression ,接下来的任务就是编译和生成,生成c#.Vb或者是.NET平台支持语言,编译程序集(dll或者是exe).       CodeDomProvider:在2.0后提供了CodeDomProvider.CreateProvider(string language)的工厂类,取代以前的   Microsoft.VisualBasic.VBCodeProvider. Microsoft.CSharp.CSharpC

CodeDom系列--事件(event)定义和反射调用

    CodeDom提供了对事件的支持,以及我们可以用反射机制对CodeDom生成的事件进行注册,以及调用.本节程序很简单,先贴上我将用CodeDom生成的代码: namespace CodeDomDemo3 { using System; public class CodeDomDemo3 { public event System.EventHandler MyEvent; protected virtual void OnHandle(System.EventArgs e) { if (

MySQL OCP考试复习系列--开篇:了解MySQL考试

嗯,那个决定去考MySQL OCP了,事实上最近工作一直围绕着DB2,MySQL要去考的话需要好好的复习的啊. 150分钟,100道多选,答对60道题可以通过,费用1077. Learn More about MySQL Database Administration Certification Oracle 认证的中级 MySQL 5.6数据库管理员(OCP) 认证 证明 你有以下能力: 安装和优化MySQL服务器:建立复制确保安全性, 执行数据库备份,以及调整和维护MySQL数据库. MyS

框架设计之菜鸟漫漫江湖路系列 开篇

自.NET世家问鼎中原以来,一路过关斩将.历经血路,时经多年,终于在江湖中占得三分有其一.   乱世之中,本人随同征战多年,历经江湖之路,自觉有所领悟,如今正值沉淀之年,愿将江湖心得写于此卷,传有缘之人. 习此卷者,虽不能神游浮云之际,但可立于苍茫之地. 未来浪迹之远近,功力之深浅,仍看各自造化,切记强大源于思想.   此卷大纲: 一:菜鸟入门:.NET世家问鼎中原之初,江湖初乱,为入世家,一同拼杀天下,勤习入门武功[SqlDataSource]. 二:自学求索:到处求索,勤习武功,略有所成,初