CodeDomProvider 生成代码

摘要:
CodeDom是.net提供源代码生成器,他可以通过CodeDomProvider来生成源代码,因为CodeDomProvider是CSharpCodeProvider、VBCodeProvider的抽象基类,表示CodeDomProvider是跨语言的源代码生成器,只需要提供相应的CodeProvider就可以生成相应的语言的源代码。CodeDom在System命名空间下,CSharpCodeProvider在Microsoft.CSharp命名空间下。

CodeDom是.net提供源代码生成器,他可以通过CodeDomProvider来生成源代码,因为CodeDomProvider是CSharpCodeProvider、VBCodeProvider的抽象基类,表示CodeDomProvider是跨语言的源代码生成器,只需要提供相应的CodeProvider就可以生成相应的语言的源代码。

CodeDom在System命名空间下,CSharpCodeProvider在Microsoft.CSharp命名空间下。VBCodeProvider在Microsoft.VisualBasic命名空间下。

CodeDom里的类及相关的用法

1.CodeCompileUnit类

这个类是用来为CodeDom程序容器提供容器,可以通过他的Namespaces集合的Add方法加入一个命名空间

如:

CodeCompileUnit unit = new CodeCompileUnit();
CodeNamespace theNamespace = new CodeNamespace("MyNamespace");
unit.Namespaces.Add(theNamespace);

2.CodeNamespace类

用来表明一个命名空间对象,这个命名空间里可以引入其他命名空间,也可以加入类

如:加入一个类到命名空间里

CodeTypeDeclaration ETClass = new CodeTypeDeclaration("ETMyClasses");
theNamespace.Types.Add(ETClass);

引入一个命名空间

CodeNamespaceImport SystemImport = new CodeNamespaceImport("System");
theNamespace.Imports.Add(SystemImport);
3.CodeTypeDeclaration类

用来表示类、结构、接口或枚举的类型声明。

声明一个类如

CodeTypeDeclaration ETClass = new CodeTypeDeclaration("ETMyClasses");BaseTypes 基类或接口的集合,通过Add方法添加
TypeAttributes 类或接口的修饰符,如public、sealed,直接赋值,可以通过|进行或运算
Members 类成员的集合,通过Add方法可以添加字段、属性、方法等
IsEnum 设置或获取这个类型是否是枚举
IsClass 设置或获取这个类型是否是类
IsInterface 设置或获取这个类型是否是接口
IsPartial 设置或获取这个类是完整声明还是部分声明
IsStruct 设置或获取这个类型是否是结构
Name 设置或获取这个类型的名称

CodeTypeDeclaration的构造函数的参数可以是这个类的名称,也可以没有参数,在实例化之后直接指定他的名称。给一个类型添加基类时可以直接使用类名称,如:ETClass.BaseTypes.Add("EntitisGateway");也可以添加CodeTypeReference的实例,如:ETClass.BaseTypes.Add(new CodeTypeReference(typeof(System.Console)));[NextPage]

4.CodeNamespaceImport类

用来表示映入的Namespace对象,构造函数参数为无参或命名空间名,通过CodeTypeDeclaration的Imports集合的Add方法添加命名空间的5.CodeMemberField类

用来表明类里面的字段对象,构造函数的参数为类型和名称如

CodeMemberField tableNameFiled = new CodeMemberField(typeof(string), "C_STR_TABLENAME");
这是表明定义了一个类型为string,名字为C_STR_TABLENAME的类成员字段

Attributes 设置类的描述符号如Const、public,可以用|进行或运算
InitExpression 初始化字段的表达式
注意对InitExpression赋值需要使用CodePrimitiveExpression类,他是用来表示使用指定对象来初始化,如:

tableFieldField.InitExpression = new CodePrimitiveExpression(field.FieldName);

6.CodeMemberProperty类

用来表明类里面的属性对象构造函数为无参构造函数Name 属性的名称
Type 属性的类型,使用CodeTypeReference来进行赋值
Attributes 表明属性的修饰符public、override
HasGet 获取或设置该属性是否有get方法访问器
HasSet 获取或设置该属性是否有set方法访问器
GetStatements 表明get方法访问器的语句集合,通过Add方法添加语句
SetStatements 表明set方法访问器的语句集合,通过Add方法添加语句

给属性的get或set方法访问器添加语句如下例:

//定义一个表达式,他用来表示一个局部变量的引用
CodeVariableReferenceExpression fieldExpression = new CodeVariableReferenceExpression("C_STR_TABLENAME");
//定一个返回语句,用来表示get的返回语句,他返回的变量是fieldExpression
CodeMethodReturnStatement propertyReturn = new CodeMethodReturnStatement(fieldExpression);
//将返回语句添加到Get的语句集合中
tableNameProperty.GetStatements.Add(propertyReturn);

7.CodeMemberMethod类

表示类里的一个成员方法,只有无参构造函数Name 表示方法名
Attributes 方法的描述符,可以通过|进行或运算
Parameters 方法的参数集合,通过Add方法添加参数
Statements 方法中的语句集合,通过Add方法添加

//构造一个方法对象
CodeMemberMethod LoadDataByProcessIDMethod = new CodeMemberMethod();
//指定方法名
LoadDataByProcessIDMethod.Name = "LoadDataByProcessID";
//指定方法的修饰符
LoadDataByProcessIDMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
//给方法添加一个类型为int,名称为ProcessID的参数,通过CodeParameterDeclarationExpression来表示一个参数
LoadDataByProcessIDMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "ProcessID"));
LoadDataByProcessIDMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(DbTransaction), "objTrans"));

//给定方法的引用,表明要调用一个方法
CodeMethodReferenceExpression LoadDataExpression = new CodeMethodReferenceExpression();
//调用的方法名
LoadDataExpression.MethodName = "LoadDataBy";
//定义方法调用的表达式,并将调用方法的引用传入,使用CodeVariableReferenceExpression来表示调用方法时传入的引用 [NextPage]
CodeMethodInvokeExpression LoadDataInvoke = new CodeMethodInvokeExpression(LoadDataExpression, new CodeVariableReferenceExpression("C_STR_PROCESSID + "=" + ProcessID"), new CodeVariableReferenceExpression("objTrans"));

//将方法调用的表达式添加到方法额语句集合中
LoadDataByProcessIDMethod.Statements.Add(LoadDataInvoke);
//将方法添加到类中
ETClass.Members.Add(LoadDataByProcessIDMethod);
CodeParameterDeclarationExpression是用指定的类型和参数名来初始化一个方法的参数。CodeVariableReferenceExpression用来表明一个局部变量名的引用

8.CodeConstructor类

用来表示一个类的构造函数,BaseConstructorArgs是用来表示基类的构造函数的参数集合,通过Add方法添加,如果基类的构造函数没有参数可以添加一个CodeVariableReferenceExpression对象,不用任何便两名初始化他,如:

wfPropertyConstructor1.BaseConstructorArgs.Add(new CodeVariableReferenceExpression());
9.CodeTypeOfExpression类

用来表示typeof表达式

10.CodeThisReferenceExpression类

用来表示this的表达式

11.CodeBaseReferenceExpression类

用来表示base的表达式

CodeThisReferenceExpression和CodeBaseReferenceExpression可以和其他表达式组合在一起形成一个表达式如:

CodeMethodInvokeExpression InitByEntityIDInvoke = new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "ConstructByID", new CodeVariableReferenceExpression(m_Model.EntitiesTable + "ID"), new CodeVariableReferenceExpression("objTrans"));
上面这段代码就是初始化一个方法调用的表达式,使用CodeBaseReferenceExpression和ConstructByID方法,加上两个局部变量的作为一个调用方法的参数组合成一个函数调用的表达式 [NextPage]

12.CodeSnippetStatement类

表明一条语句,由于CodeDom为了兼容VB的语法,有些语法不支持,没有类可以调用,实在没有办法了可以通过CodeSnippetStatement来写一条语句,但这个语句不能保证在VB.Net里被通过

CodeSnippetStatement ExceptionStatement = new CodeSnippetStatement("throw new Exception("Property not Implementation")");
上面这条抛出异常的语句是直接写的代码,当然CodeDom存在异常语句的对象,我这里偷了一下懒

13.IndentedTextWriter类

表明生成出来代码语句的缩进

IndentedTextWriter tw = new IndentedTextWriter(new StreamWriter(sourceCodePaht + "\" + m_Model.EntitiesAssembly + ".cs", false), " ");

false后面的双引号之间的四个空格表明代码的缩进值为四个空格

那么我们剩下的就是生成代码了

IndentedTextWriter tw = new IndentedTextWriter(new StreamWriter(sourceCodePaht + "\" + m_Model.EntitiesAssembly + ".cs", false), " ");
CodeDomProvider provide = new CSharpCodeProvider();

provide.GenerateCodeFromCompileUnit(unit, tw, new CodeGeneratorOptions());
tw.Close();
provider提供几种生成,GenerateCodeFromCompileUnit可以生成的直接生成一个代码容器里的所有代码,如果我们只写了一个类,可以通过GenerateCodeFromType方法生成,也可以生成一个命名空间里的代码,甚至可以只生成一条语句或一个表达式GenerateCodeFromNamespace、GenerateCodeFromStatement

剩下的就是要编译源代码了

CompilerParameters compilerParams = new CompilerParameters();
//指定编译选项,是类库
compilerParams.CompilerOptions = "/target:library /optimize";
//不生成执行文件
compilerParams.GenerateExecutable = false;
//在内存中生成输出
compilerParams.GenerateInMemory = true;
//不包含调试信息
compilerParams.IncludeDebugInformation = false;
//添加编译时使用的dll,如果不是系统自带的dll,必须指定完整的路径
compilerParams.ReferencedAssemblies.Add("mscorlib.dll");
compilerParams.ReferencedAssemblies.Add("System.dll");
compilerParams.ReferencedAssemblies.Add("System.Data.dll");
compilerParams.ReferencedAssemblies.Add(AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "DawnPro.WebArchitechture.DAL.dll");
compilerParams.ReferencedAssemblies.Add(AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "DawnPro.WorkflowInterface.dll");
//指定编译后的文件的输出路径
compilerParams.OutputAssembly = outputAsseblyPath + "\bin\" + m_Model.EntitiesAssembly + ".dll";最后使用Provider提供的CompileAssemblyFromDom方法进行编译,provider提供了三种方法,一种是从Dom,还有一种从文件,一种从字符串中编译CompilerResults result = provide.CompileAssemblyFromDom(compilerParams, unit);CompilerResults是这三种方法的返回值,可以通过CompilerResults的Errors集合来查看编译的错误。

文章转载自网管网:http://www.bitscn.com/pdb/dotnet/200803/135308.html

另外:http://blog.csdn.net/heguodong/archive/2009/12/28/5094185.aspx

免责声明:文章转载自《CodeDomProvider 生成代码》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Spring各个jar包的简介JENKINS针对不同项目组对用户进行权限分配下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

关于C++里set_intersection(取集合交集)、set_union(取集合并集)、set_difference(取集合差集)等函数的使用总结

文章转载自https://blog.csdn.net/zangker/article/details/22984803 set里面有set_intersection(取集合交集)、set_union(取集合并集)、set_difference(取集合差集)、set_symmetric_difference(取集合对称差集)等函数。其中,关于函数的五个参数问...

C++的隐式类型转换

C++是一种复杂的语言,其中有许多“好玩”的特性,学习C++的过程就像在海边捡一颗颗石头,只要坚持不懈,也许一颗颗小石头也能建起你自己小小的城堡。 废话完后,讲讲自己捡到的石头:隐式类型转换  学习出处:《Effective C++》 lostmouse大人翻译 class TestInt{ public:    int GetData()const{...

ES6-10笔记(class类)

class类 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类)。摘自阮一峰老师语录 class声明 ES5的JavaScript中只有对象,想要模拟类去生成一个对象实例,只能通过定义一个构造函数,然后通过new操作符来完...

对JS中继承的思考

名词理解:   prototype属性,是函数对象特有的属性,不存在其他对象中(函数也是对象)。每当创建一个新函数,该函数就会自动包含一个prototype属性,这个属性用来指向函数的原型对象。   prototype对象,即原型对象。 原型对象里包含着实例中需要共享的属性和方法。这里要注意,由于原型对象本身就是对象,那么默认的原型对象也是Object对...

python 多重继承构造函数调用顺序

实例代码 class Person(object): def __init__(self, name, age): self.name = name self.age = age print("父类构造函数") def talk(self): print("person...

C# 类类型

1、一旦定义了自定义构造函数,默认的构造函数就会被移除2、可以使用this设计构造函数链,将核心部分代码由主构造函数完成,其余的构造函数调用主构造函数就可以了3、静态构造函数适合初始化静态数据成员(这个初始化发生在编译时)4、防止创建类对象的方式: 定义静态类 将构造函数声明为私有的(private) 将类声明为抽象的(abstract) 5、OOP...