DCG(Dynamic Code Generator)

题外话,我最近怎么总是在周二写Blog啊?看看Blog上的日历,全都是周二写的!^_^

言规正传,最近为了一个项目需要动态生成代码特地写了另一个小“项目”,动态代码生成器。其实就是动态的模板,一个有差不多ASP.NET语法的模板,应该说与CodeSmith的功能是一样的,只不过现在还没有编辑器。目前提供了一个DLL,可以提供所有需要构建一个模板编辑器所需要的信息,包括动态模板的编译时错误以及运行时错误等。

我在这个小项目中运用了很多学到的新知识,自我感觉在这个小项目中运用的设计是目前为止运用的最好的一次。^_^

下面描述一下模板的语法与使用方法:

@ Template Language="C#" Name="" Version=""

 1
 2  * ```
 3@ Parameter Name="ParamName" DataType="System.String" AssemblyName="" 
 4```:模板参数,其中的所有属性都是必须的,当参数类型的的所在程序集为mscorlib.dll时需要将AssemblyName属性设为空。一个模板可以有多个参数。 
 5
 6  * ```
 7 code 
 8```:模板中的动态代码,在其中可以用模板Language属性所指定的语言写入动态代码。 
 9
10  * ```
11= variable 
12```:模板中的动态代码,会将动态代码的结果返回,注意如果动态代码不返回任何结果的话,那么就会产生编译错误。 
13
14  * ```
15# void Method() 
16```:动态方法,在模板中可以简单的定义动态方法,这样就可以直接在其他动态代码部分调用这个动态方法。 
17
18  * ```
19-- comment --
20```:动态模板中的注释。 
21
22
23
24
25模板本身不是Case Sensitive,不过每个Tag属性中的值就要根据模板运用的语言来定是否是Case Sensitive了。比如如果是C#,那么就是Case Sensitive,如果是VB.NET那就不是了。 
26
27下面是C#的示例: 
28
29模板为: 

@ Template Name="Sample1" Version="1.0" language="C#"

@ Parameter Name="Entity" DataType="Kefroth.Entity" AssemblyName="DCGTest.exe"

1
2using System; 
3
4// 这是一段中文注释。   

-- 模板注释 --

1namespace ```
2= Entity.Namespace 
3``` {   
4public sealed class ```
5=Entity.Name
6``` {   
7public static void CallMe() {   
8ArrayList list = new ArrayList();   

for (int i = 1; i <= 10; i++) {

1list.Add("```
2= GetEntityName() + i
3```");   

}

1}   
2}   
3}   

string GetEntityName() {

return Entity.GetFullName();
}

 1
 2调用模板的代码为: 
 3
 4string fileContent = this.ReadFile(Application.StartupPath + "\\\" + "Sample Template.dt"); 
 5
 6Entity ent = new Entity();   
 7ent.Namespace = "SampleNamespace";   
 8ent.Name = "SampleEntity";   
 9ITemplateManager templateManager = new TemplateManager();   
10try {   
11ITemplate template = templateManager.NewTemplate(fileContent);   
12this.textBox1.SelectedText += "This template's name is: " + template.Name + Environment.NewLine;   
13this.textBox1.SelectedText += "This template's language is: " + template.Language + Environment.NewLine + Environment.NewLine;   
14this.textBox1.SelectedText += template.GenerateCode(new object[] {ent});   
15} catch (CompileTimeException ex) {   
16this.textBox1.Clear();   
17foreach (CompilerError error in ex.CompilerResults.Errors) {   
18this.textBox1.SelectedText += error.ErrorText + Environment.NewLine;   
19}   
20return;   
21} catch (RunTimeException ex) {   
22this.textBox1.Clear();   
23this.textBox1.SelectedText += ex.InnerException.InnerException.ToString() + Environment.NewLine;   
24return;   
25} catch (TemplateException ex) {   
26this.textBox1.Clear();   
27this.textBox1.SelectedText += ex.ToString() + Environment.NewLine;   
28return;   
29} 
30
31结果为: 
32
33This template's name is: Sample1   
34This template's language is: C# 
35
36using System; 
37
38// 这是一段中文。   
39namespace SampleNamespace {   
40public sealed class SampleEntity {   
41public static void CallMe() {   
42ArrayList list = new ArrayList();   
43list.Add("SampleNamespace.SampleEntity1");   
44list.Add("SampleNamespace.SampleEntity2");   
45list.Add("SampleNamespace.SampleEntity3");   
46list.Add("SampleNamespace.SampleEntity4");   
47list.Add("SampleNamespace.SampleEntity5");   
48list.Add("SampleNamespace.SampleEntity6");   
49list.Add("SampleNamespace.SampleEntity7");   
50list.Add("SampleNamespace.SampleEntity8");   
51list.Add("SampleNamespace.SampleEntity9");   
52list.Add("SampleNamespace.SampleEntity10");   
53}   
54}   
55} 
56
57从代码中可以看出调用是非常简单的,而且可以非常轻松的集成在任何项目中,这就达到了我的初始目的。CodeSmith可以做到这一切,当却不能轻松的集成到其他项目中去。 
58
59这样一个动态代码生成器的用途无异是非常广的,不过我希望看到这篇文章的读者能够给我提出更好的意见,或是讨论,来使DCG更加完美!^_^
Published At
Categories with Web编程
Tagged with
comments powered by Disqus