zoukankan      html  css  js  c++  java
  • 【转】codesmith模板编写要点

    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层代码模板。

  • 相关阅读:
    清北学堂 清北-Day1-R1-Count
    清北学堂 清北-Day1-R2-监听monitor
    LuoGu P2420 让我们异或吧
    Milk(sort+结构体)
    开门人和关门人(结构体+sort)
    python-神奇的下划线
    python-pathlib
    python-文本字符串
    python-闭包
    进制-Iterative-进制转换
  • 原文地址:https://www.cnblogs.com/sekihin/p/810415.html
  • Copyright © 2011-2022 走看看
    Creative Commons License 本作品采用 知识共享署名-非商业性使用 2.5 中国大陆许可协议进行许可。