鍍金池/ 教程/ C++/ Merge 策略
使用主從代碼模板
CodeTemplateInfo 對(duì)象
引用其它文件或 .Net 類庫
編寫第一個(gè)代碼模板
Progress 對(duì)象
基本語法-使用注釋
基本語法-轉(zhuǎn)義Asp.Net標(biāo)記
調(diào)試
為 Yii Framework 創(chuàng)建生成 ActiveRecord 的代碼模板
基本語法-聲明和使用屬性
自動(dòng)生成Yii Framework ActiveRecord類簡(jiǎn)單模板
Merge 策略
使用 XMLProperty
CodeTemplate 對(duì)象
基本語法-CodeTemplate 指令
概述
使用 SchemaExplorer 來獲取數(shù)據(jù)庫定義

Merge 策略

前面介紹了 CodeSmith 使用的基本用法,通過代碼模板來生成代碼,但如果你修改了自動(dòng)生成的代碼,再次使用代碼模板生成代碼后,你修改的代碼也就丟失了,CodeSmith 支持多種“合并(Merge)”來解決這個(gè)問題,以保留你自己修該過的部分。

CodeSmith 支持如下三種“合并策略”:

不過這些策略主要是針對(duì) C#,VB 這些支持 Region 的語言,對(duì)于其它語言可能就需要使用其它方法,比如自定義 Merge 策略,CodeSmith 允許通過 CodeSmith.Engine.IMergeStrategy 來擴(kuò)展“合并”策略,本人推薦 CodeSmith 的一個(gè)原因就是 CodeSmith 提供了很多接口而不僅僅是一個(gè)工具,比如除了 CodeSmith 支持的屬性,XML 屬性,你也可以通過 CodeSmith.CustomProperties 來自定義屬性種類,除了 CodeSmith 支持的數(shù)據(jù)源種類(MySQL,Oracle),你也可以通過自定義的 Schema Provider 支持新的數(shù)據(jù)庫類型或是其它數(shù)據(jù)類型。

InsertRegion 策略

InsertRegion 顧名思義,就是在源碼中定義一個(gè) Region,然后讓 CodeSmith 自動(dòng)生成的代碼只插入到該區(qū)域,而在區(qū)域外的代碼 CodeSmith 不會(huì)去碰它們,從而實(shí)現(xiàn)了自定義的代碼和自動(dòng)生成代碼的合并。

PreserveRegion 策略

PreserveRegion 是定義多個(gè)區(qū)域,然后通知 CodeSmith 保持這些區(qū)域代碼不變,自動(dòng)創(chuàng)建的代碼添加到這些區(qū)域的外面,和 InsertRegion 作用相反。

下面還是借用 CodeSmith 自帶的 Merge 示例說明一下這兩種策略的基本用法:

首先是 InsertRegion 策略,定義一個(gè)類文件 InsertRegionSample.cs

public class InsertRegionsSample
{

    public void SomeCustomMethod()
    {
        // This is my custom code that I want to preserve.
        // I can make changes to it and my changes will
        // not be overwritten.
    }

    #region Sample Generated Region
// This region generated by CodeSmith on Saturday, 12 January 2013
    #endregion
}

其中定義了一個(gè) Region,名為 Sample Generated Region ,準(zhǔn)備讓 CodeSmith 查入代碼,編寫一個(gè)簡(jiǎn)單的代碼模板,插入當(dāng)前時(shí)間:

<%@ Template Language="C#" TargetLanguage="C#"   Description="Demonstrates using an InsertRegion merge strategy in C#." %>
// This region generated by CodeSmith on <%= DateTime.Now.ToLongDateString() %>

然后通過 CodeSmith 項(xiàng)目為模板設(shè)置 Merge 策略:

http://wiki.jikexueyuan.com/project/codesmith/images/33.png" alt="第33張" />

選擇 InsertRegion 策略, 然后設(shè)置要插入的 RegionName。

生成后的代碼如下:

public class InsertRegionsSample
{

    public void SomeCustomMethod()
    {
        // This is my custom code that I want to preserve.
        // I can make changes to it and my changes will
        // not be overwritten.
    }

    #region Sample Generated Region
// This region generated by CodeSmith on Saturday, 12 January 2013
    #endregion
}

可以看到 CodeSmith 只在 Region 處插入代碼,而該 Region 外的部分保持不變。

類似的 PreserveRegions 策略,代碼和模板定義如下: PreserveRegionsSample.cs

public class PreserveRegionsSample
{

#region "Custom Region 1"

    // This is a place holder for your custom code.
    // It must exist so that CodeSmith knows where
    // to put the custom code that will be parsed
    // from the target source file.
    // The region name is used to match up the regions
    // and determine where each region of custom code
    // should be inserted into the merge result.

#endregion

    public void SomeGeneratedMethod()
    {

        // This section and all other non-custom code
        // regions will be overwritten during each
        // template execution.
        // Current Date: Saturday, 12 January 2013
    }

#region "Custom Region 2"

    // The contents of this region will also be preserved
    // during generation.

#endregion

}

模板定義如下:

<%@ Template Language="C#" TargetLanguage="C#"    Description="Demonstrates using a PreserveRegions merge strategy in C#." %>
public class PreserveRegionsSample
{

#region "Custom Region 1"

    // This is a place holder for your custom code.
    // It must exist so that CodeSmith knows where
    // to put the custom code that will be parsed
    // from the target source file.
    // The region name is used to match up the regions
    // and determine where each region of custom code
    // should be inserted into the merge result.

#endregion

    public void SomeGeneratedMethod()
    {

        // This section and all other non-custom code
        // regions will be overwritten during each
        // template execution.
        // Current Date: <%= DateTime.Now.ToLongDateString() %>
    }

#region "Custom Region 2"

    // The contents of this region will also be preserved
    // during generation.

#endregion

}

模板中也定義了兩個(gè)區(qū)域,然后為該模板設(shè)置 Merge 策略,使用 PreserveRegion 時(shí)可能有多個(gè)Region 需要保留,因此可以使用 RegX 來定義要保留的 Region:

http://wiki.jikexueyuan.com/project/codesmith/images/34.png" alt="第34張" />

本例下載

InsertClass 策略用在給以重載的代碼中插入自動(dòng)生成的代碼,挺起來和 InsertRegion 功能很類似,的確也是如此,但 InsertClass 支持更多的配置,可以實(shí)現(xiàn)更加靈活和強(qiáng)大的功能。

它支持的配置有:

Language String, Required 只支持VB和C#
ClassName String, Required 需插入代碼的類名.
PreserveClassAttributes Boolean, defaults to False 是否保留類已有的Attributes,缺省CodeSmith替代類原來的Attributes
OnlyInsertMatchingClass Boolean, defaults to False 是否只插入匹配的類定義中
MergeImports Boolean, defaults to False 是否合并Import語句
NotFoundAction Enum, defaults to None 如果指定的類沒找到后的行動(dòng),可以None,InsertAtBottom,InsertInParent幾種選項(xiàng)
NotFoundParent String, no default 如果指定NotFoundAction為InsertInParent對(duì)應(yīng)的父類名稱.

比如使用如下配置:

Language: C# ClassName: “Pet” PreserveClassAttributes: True OnlyInsertMatchingClass: True MergeImports: True

現(xiàn)有類定義:

using System;
using System.ComponentModel.DataAnnotations;
namespace Petshop
{
    [ScaffoldTable(true)]
    public class Pet
    {
        public int Age { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

自動(dòng)生成的代碼如下:

using System;
using System.Text;
namespace Petshop
{
    public class Pet
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string FullName
        {
            get { return String.Format("{0} {1}", FirstName, LastName); }

        }
    }
}

使用 InsertClass 合并后的代碼如下:

using System;
using System.ComponentModel.DataAnnotations;
using System.Text;
namespace Petshop
{
    [ScaffoldTable(true)]
    public class Pet
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string FullName
        {
            get { return String.Format("{0} {1}", FirstName, LastName); }

        }
    }
}
上一篇:概述下一篇:CodeTemplateInfo 對(duì)象