zoukankan      html  css  js  c++  java
  • CodeSmith : Merge策略

    通过代码模板来生成代码,但如果你修改了自动生成的代码,再次使用代码模板生成代码后,你修改的代码也就丢失了,CodeSmith 支持多种“合并(Merge)”来解决这个问题,以保留你自己修该过的部分。

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

    不过这些策略主要是针对C#,VB这些支持Region的语言,对于其它语言可能就需要使用其它方法,比如自定义Merge策略,CodeSmith允许通过CodeSmith.Engine.IMergeStrategy 来扩展“合并”策略,本人推荐CodeSmith的一个原因就是CodeSmith提供了很多接口而不仅仅是一个工具,比如除了CodeSmith支持的属性,XML属性,你也可以通过 CodeSmith.CustomProperties来自定义属性种类,除了CodeSmith支持的数据源种类(MySQL,Oracle),你也可以通过自定义的Schema Provider 支持新的数据库类型或是其它数据类型。

    InsertRegion策略

    InsertRegion 顾名思义,就是在源码中定义一个Region,然后让CodeSmith自动生成的代码只插入到该区域,而在区域外的代码CodeSmith不会去碰它们,从而实现了自定义的代码和自动生成代码的合并。

    PreserveRegion策略

    PreserveRegion 是定义多个区域,然后通知CodeSmith保持这些区域代码不变,自动创建的代码添加到这些区域的外面,和InsertRegion作用相反。

    下面还是借用CodeSmith 自带的Merge示例说明一下这两种策略的基本用法:

    首先是InsertRegion策略,定义一个类文件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  
        }  

    其中定义了一个Region,名为Sample Generated Region ,准备让CodeSmith查入代码,编写一个简单的代码模板,插入当前时间:

    <%@ Template Language="C#" TargetLanguage="C#"   Description="Demonstrates using an InsertRegion merge strategy in C#." %> 

    然后通过CodeSmith项目为模板设置Merge策略:

    20130112002

    选择InsertRegion策略, 然后设置要插入的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  
          
        }  

    模板中也定义了两个区域,然后为该模板设置Merge策略,使用PreserveRegion时可能有多个Region需要保留,因此可以使用RegX来定义要保留的Region:
    20130112003

    InsertClass 策略用在给以重载的代码中插入自动生成的代码,挺起来和InsertRegion功能很类似,的确也是如此,但InsertClass支持更多的配置,可以实现更加灵活和强大的功能。

    它支持的配置有:

    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 如果指定的类没找到后的行动,可以None,InsertAtBottom,InsertInParent几种选项
    NotFoundParent String, no default 如果指定NotFoundAction为InsertInParent对应的父类名称.

    比如使用如下配置:

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

    现有类定义:

        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; }  
            }  
        }  

    自动生成的代码如下:

        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); }  
          
                }  
            }  
        }  

  • 相关阅读:
    Canvas 基本绘图方法总结
    js: 从setTimeout说事件循环模型
    HTML5 表单元素
    jQuery选择器
    jQuery基本动画
    HangFire循环作业中作业因执行时间太长未完成新作业开启导致重复数据的问题
    .net 上传文件 Failed to load resource: net::ERR_CONNECTION_RESET Bug 解决
    ABP Zero项目入门踩坑
    关于toggle事件委托的处理
    关于height,line-height导致的样式混乱的问题
  • 原文地址:https://www.cnblogs.com/ful1021/p/4804429.html
Copyright © 2011-2022 走看看