课程表

CodeSmith课程

工具箱
速查手册

CodeSmith Merge 策略

当前位置:免费教程 » 软件/图像 » CodeSmith

前面介绍了 CodeSmith 使用的基本用法,通过代码模板来生成代码,但如果你修改了自动生成的代码,再次使用代码模板生成代码后,你修改的代码也就丢失了,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

  1. public class InsertRegionsSample
  2. {
  3. public void SomeCustomMethod()
  4. {
  5. // This is my custom code that I want to preserve.
  6. // I can make changes to it and my changes will
  7. // not be overwritten.
  8. }
  9. #region Sample Generated Region
  10. // This region generated by CodeSmith on Saturday, 12 January 2013
  11. #endregion
  12. }

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

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

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

第33张

选择 InsertRegion 策略, 然后设置要插入的 RegionName。

生成后的代码如下:

  1. public class InsertRegionsSample
  2. {
  3. public void SomeCustomMethod()
  4. {
  5. // This is my custom code that I want to preserve.
  6. // I can make changes to it and my changes will
  7. // not be overwritten.
  8. }
  9. #region Sample Generated Region
  10. // This region generated by CodeSmith on Saturday, 12 January 2013
  11. #endregion
  12. }

可以看到 CodeSmith 只在 Region 处插入代码,而该 Region 外的部分保持不变。

类似的 PreserveRegions 策略,代码和模板定义如下: PreserveRegionsSample.cs

  1. public class PreserveRegionsSample
  2. {
  3. #region "Custom Region 1"
  4. // This is a place holder for your custom code.
  5. // It must exist so that CodeSmith knows where
  6. // to put the custom code that will be parsed
  7. // from the target source file.
  8. // The region name is used to match up the regions
  9. // and determine where each region of custom code
  10. // should be inserted into the merge result.
  11. #endregion
  12. public void SomeGeneratedMethod()
  13. {
  14. // This section and all other non-custom code
  15. // regions will be overwritten during each
  16. // template execution.
  17. // Current Date: Saturday, 12 January 2013
  18. }
  19. #region "Custom Region 2"
  20. // The contents of this region will also be preserved
  21. // during generation.
  22. #endregion
  23. }

模板定义如下:

  1. <%@ Template Language="C#" TargetLanguage="C#" Description="Demonstrates using a PreserveRegions merge strategy in C#." %>
  2. public class PreserveRegionsSample
  3. {
  4. #region "Custom Region 1"
  5. // This is a place holder for your custom code.
  6. // It must exist so that CodeSmith knows where
  7. // to put the custom code that will be parsed
  8. // from the target source file.
  9. // The region name is used to match up the regions
  10. // and determine where each region of custom code
  11. // should be inserted into the merge result.
  12. #endregion
  13. public void SomeGeneratedMethod()
  14. {
  15. // This section and all other non-custom code
  16. // regions will be overwritten during each
  17. // template execution.
  18. // Current Date: <%= DateTime.Now.ToLongDateString() %>
  19. }
  20. #region "Custom Region 2"
  21. // The contents of this region will also be preserved
  22. // during generation.
  23. #endregion
  24. }

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

第34张

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

现有类定义:

  1. using System;
  2. using System.ComponentModel.DataAnnotations;
  3. namespace Petshop
  4. {
  5. [ScaffoldTable(true)]
  6. public class Pet
  7. {
  8. public int Age { get; set; }
  9. public string FirstName { get; set; }
  10. public string LastName { get; set; }
  11. }
  12. }

自动生成的代码如下:

  1. using System;
  2. using System.Text;
  3. namespace Petshop
  4. {
  5. public class Pet
  6. {
  7. public string FirstName { get; set; }
  8. public string LastName { get; set; }
  9. public string FullName
  10. {
  11. get { return String.Format("{0} {1}", FirstName, LastName); }
  12. }
  13. }
  14. }

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

  1. using System;
  2. using System.ComponentModel.DataAnnotations;
  3. using System.Text;
  4. namespace Petshop
  5. {
  6. [ScaffoldTable(true)]
  7. public class Pet
  8. {
  9. public string FirstName { get; set; }
  10. public string LastName { get; set; }
  11. public string FullName
  12. {
  13. get { return String.Format("{0} {1}", FirstName, LastName); }
  14. }
  15. }
  16. }
转载本站内容时,请务必注明来自W3xue,违者必究。
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号