stepwin原创,来自于www.softboss.com原创
//模板的基础知识
//任何模板都需要的第一句,用来指定模板编辑语言是什么,目标语言是什么: <%@ CodeTemplate Language="C#" TargetLanguage="T-SQL" Description="Generates a update stored procedure." %>
//接下来写模板需要从外界引入的参数 <%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" Category="Context" Description="Database" %>
//在模板里面用到了codesmith的函数和方法,需要引入对应的包,一般是 <%@ Assembly Name="SchemaExplorer" %> <%@ Import Namespace="SchemaExplorer" %>
我理解assembly 是引入dll,import 是引入dll里面的命名空间,这些dll有的是codesmith自己带的,对于vs.net提供的dll,都可以引入使用。
//所有codesmith函数都在script标签里面定义,包括变量 <script runat="template"> private string _outputDirectory = String.Empty;
</script>
调用用<% %> 括起来,一般有一个主函数来执行整个模板的函数 <% this.Go(); %>
将生成的变量插入到模板的任何需要动态生成的地方,直接用asp的写法就可以了,例如 namespace <%=DALNameSpace%>.SqlClient
//一般模板的函数和用法
/// <summary> /// 拷贝指定文件 /// </summary> public void SafeCopyFile(string path, string destination) { FileInfo file1 = new FileInfo(path); file1.CopyTo(destination, true); }
/// <summary> /// 创建指定目录 /// </summary> public void SafeCreateDirectory(string path) { if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } }
/// <summary> /// 根据指定模板生成指定文件 /// </summary> public void RenderToFile(string templateName, string path, bool overwrite) { this._CurrentFileName = path; this.GetTemplate(templateName).RenderToFile(path, overwrite); this._counter++; }
/// <summary> /// 打开文件目录,[Editor]标签表示调用指定的编辑器;category表示参数所属目录;Descript表示对参数的描述;defaultvalue表示缺省值 CodeTemplateProperty表示该参数是可选还是必须的,CodeTemplatePropertyOption.Optional是可选,CodeTemplatePropertyOption.Required是必
须 /// </summary> private string _outputDirectory = String.Empty; [Editor(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))] [CodeTemplateProperty(CodeTemplatePropertyOption.Optional)] [Category("General")] [Description("The directory to output the results to.")] [DefaultValue("")] public string OutputDirectory { get { if (_outputDirectory.Length == 0) { return @"c:\NetTiers\Output"); } else { return _outputDirectory; } } set { if (value.EndsWith("\\")) value = value.Substring(0, value.Length - 1); _outputDirectory = value; } }
//获取当前打开模板所在路径 this.CodeTemplateInfo.DirectoryName
//对于模板,当前打开的模板可以用codeTemplateInfo访问,其他的子模板需要先根据文件名和路径载入,然后编辑模板,最后赋予参数,生成文件。
//设定模板路径 private string[] _templatesFileNames = new string[] { "vsnet2003.project.cst", "vsnet2005.project.cst", "vsnet2003.solution.cst", "vsnet2005.solution.cst", "ASP.Net\\2.0\\Entty_aspx_resx.cst" };
//设定编辑好的子模板保存的hashtable,在hashtable里面,key是文件名,所以全套模板不能有重复的文件名 // Compile and load all them in a collection private System.Collections.Hashtable _CodeTemplates = new System.Collections.Hashtable();
//载入模板 // load all the templates and put them into an hashtable public void LoadTemplates() { foreach(string _templatesFileName in _templatesFileNames) { string key = System.IO.Path.GetFileName(_templatesFileName);
if (_CodeTemplates.Contains(key)) { continue; }
_CodeTemplates.Add(key, this.CompileTemplate(this.CodeTemplateInfo.DirectoryName + _templatesFileName));
// Set the properties that all the commonsqlcode inherited templates should set // TODO : use reflection to check that the templates inherits from commonsql try { ((CodeSmith.Engine.CodeTemplate)_CodeTemplates[key]).SetProperty("EntityFormat", EntityFormat); ((CodeSmith.Engine.CodeTemplate)_CodeTemplates[key]).SetProperty("CollectionFormat",
CollectionFormat); ((CodeSmith.Engine.CodeTemplate)_CodeTemplates[key]).SetProperty("ProviderFormat", ProviderFormat); ((CodeSmith.Engine.CodeTemplate)_CodeTemplates[key]).SetProperty("InterfaceFormat", InterfaceFormat); ((CodeSmith.Engine.CodeTemplate)_CodeTemplates[key]).SetProperty("BaseClassFormat", BaseClassFormat); ((CodeSmith.Engine.CodeTemplate)_CodeTemplates[key]).SetProperty("EnumFormat", EnumFormat); ((CodeSmith.Engine.CodeTemplate)_CodeTemplates[key]).SetProperty("ManyToManyFormat",
ManyToManyFormat); ((CodeSmith.Engine.CodeTemplate)_CodeTemplates[key]).SetProperty("AliasFilePath", AliasFilePath); ((CodeSmith.Engine.CodeTemplate)_CodeTemplates[key]).SetProperty("StrippedTablePrefixes",
StrippedTablePrefixes); } catch(Exception) {} } }
//载入的时候都需要编译模板 public CodeTemplate CompileTemplate(string templateName) { this._CurrentFileName = templateName;
CodeTemplateCompiler compiler = new CodeTemplateCompiler(templateName); compiler.Compile();
if (compiler.Errors.Count == 0) { return compiler.CreateInstance(); } else { for (int i = 0; i < compiler.Errors.Count; i++) { Response.WriteLine(compiler.Errors[i].ToString()); } return null; } }
//获取模板 public CodeTemplate GetTemplate(string templateType) { return (CodeSmith.Engine.CodeTemplate)_CodeTemplates[templateType]; }
//给模板赋值 this.GetTemplate("EntityProviderBase.cst").SetProperty("SourceTable", SourceTable);
//数据库属性 <%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" Optional="False" Category="DataSource"
Description="Database that the stored procedures should be based on." %>
//遍历数据库里面的所有数据表 private TableSchemaCollection _sourceTables; private ViewSchemaCollection _sourceViews; for (int i=0; i < SourceDatabase.Tables.Count; i++) { _sourceTables.Add(SourceDatabase.Tables[i]); }
//遍历数据库里面的所有视图 for (int i=0; i < SourceDatabase.Views.Count; i++) { _sourceViews.Add(SourceDatabase.Views[i]); }
//获取表格名 SourceTables[i].Name
//遍历表的结构 for (int i=0; i< SourceTable.Columns.Count; i++) { Response.Write("\""+ SourceTable.Columns[i].Name + "\""); }
//指定打开哪个或者哪几个表 [Category("DataSource")] [Description("The tables to generate.")] [CodeTemplateProperty(CodeTemplatePropertyOption.Optional)] public TableSchemaCollection SourceTables { get { if (this._sourceTables != null && this._sourceTables.Count > 0 ) return this._sourceTables; else return null; } set { this._sourceTables = value; } }
//关于遍历文件夹和拷贝文件夹里面所有文件是我自己写的,在nettiers里面没有用例: //拷贝目录 public void CopyDirectory(string path) { SafeCreateDirectory(OutputDirectory+path);
DirectoryInfo dir = new DirectoryInfo(this.CodeTemplateInfo.DirectoryName+path); FileInfo[] fileList = dir.GetFiles(); foreach (FileInfo sourceFile in fileList) { sourceFile.CopyTo(OutputDirectory + path+"\\"+sourceFile.Name, true); Response.WriteLine("Copy file: " + sourceFile.Name); } }
//遍历文件夹:先打开目录,然后载入目录下的文件,这个操作完全是用c#代码来写的,更多功能可以参考msdn DirectoryInfo dir = new DirectoryInfo(this.CodeTemplateInfo.DirectoryName+path); FileInfo[] fileList = dir.GetFiles(); foreach (FileInfo sourceFile in fileList) { sourceFile.CopyTo(OutputDirectory + path+"\\"+sourceFile.Name, true); Response.WriteLine("Copy file: " + sourceFile.Name);
}
//完整例子请参阅nettiers,这是一个相当不错的完整的例子,美中不足是没有web层代码模板。
附件: nettiers-fx1.1-20060510.zip 947 KB, 下载 1 次. codesmith模板编写要点.pdf 37 KB, 下载 1 次.
|