CodeSmith 它是一种基于模板的代码生成工具,类似于使用 ASP.NET 语法生成任何类型的代码或文本。与许多其他代码生成工具不同,CodeSmith 不要求您订阅特定的应用程序设计或系统结构。使用 CodeSmith,它可以生成任何东西,包括简单的强类型集合和完整的应用程序。当您生成应用程序时,您通常需要重复一些特定的任务,如编写数据访问代码或生成自定义集合。CodeSmith 这些时候特别有用,因为你可以自动编写模板来完成这些任务,这不仅可以提高你的工作效率,还可以自动完成最无聊的任务。CodeSmith 附带了许多模板,包括所有对应的模板 .NET 集合模板和用于生成存储过程的模板,但该工具的真正力量在于创建自定义模板。
codesmith简介
CodeSmith 它是一种基于模板的代码生成工具,类似于使用 ASP.NET 语法生成任何类型的代码或文本。与许多其他代码生成工具不同,CodeSmith 不要求您订阅特定的应用程序设计或系统结构。使用 CodeSmith,它可以生成任何东西,包括简单的强类型集合和完整的应用程序。当您生成应用程序时,您通常需要重复一些特定的任务,如编写数据访问代码或生成自定义集合。CodeSmith 这些时候特别有用,因为你可以自动编写模板来完成这些任务,这不仅可以提高你的工作效率,还可以自动完成最无聊的任务。CodeSmith 附带了许多模板,包括所有对应的模板 .NET 集合模板和用于生成存储过程的模板,但该工具的真正力量在于创建自定义模板。
为什么要使用代码生成器²代码生成器生成代码可以减少人工误写的bug
²可提高代码开发效率,简化开发过程
²输出文档和代码可以标准化
编写代码生成模板
asp用于生成模板.Net语法编写,语法简单易懂,熟悉asp.net开发人员非常友好。即使没有asp。.net开发也可以在简单学习后编写模板。
1. 编写模板的基础需要引入数据表,一些生成代码的配置项可以简单地引入到模板中
1.<%@ CodeTemplate Language="C#" TargetLanguage="Java" Src="" Inherits="" Debug="False" Description="" ResponseEncoding="UTF-8" %> 2.<%@ Property Name="package" Type="System.String" Default="Che168.Model" Optional="False" Category="Strings" Description=“实体类命名空间” %> 3.<%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Optional="False" Category="Configs" Description="源表" %> 4.<%@ Property Name=“Sourcetable2” Type="SchemaExplorer.TableSchema" Optional="True" Category="Configs" Description=“字段备注来源表” %> 5.<%@ Property Name=“Sourcetable3” Type="SchemaExplorer.TableSchema" Optional="True" Category="Configs" Description=“字段备注来源表” %> 6.<%@ Property Name=“Sourcetable4” Type="SchemaExplorer.TableSchema" Optional="True" Category="Configs" Description=“字段备注来源表” %>7.<%@ Property Name="IsSpringBoot" Type="System.Boolean" Category="Configs" Description=“SpringBotot吗? bean,如果是这样,生成api说明备注“ %>
Name:注册配置引用名称
Description:配置项目说明
Type:支持内置和控件的类型.net的类型
SchemaExplorer.TableSchema:为数据源表的选择
System.String:将控件输入文本
Optional:是否可选, False是必填
IsSpringBoot:这是我们选择生成的bean是否生成swagger说明
2.引入配置项后,您可以继续编写代码模板
例如,生成java的bean
1.package <%=package%>import java.util.*; 2. <%if(IsSpringBoot){ %> 3.import io.swagger.annotations.*; 4.<%} %> 5. 6./** 7.* <%=SourceTable.Description%>bean 8.*/ 9.public class <%= SourceTable.Name%> 10.{ 11. <% foreach (ColumnSchema column in SourceTable.Columns) { %> 12. /**<%= column.Description %>*/ 13. <%if(IsSpringBoot){ %> 14. @ApiModelProperty(value = "<%= column.Description %>", name = "<%= column.Name.ToLower() %>") 15. <%} %> 16. <%= GetJavaType(column.DataType) %> <%= column.Name.ToLower() %> ; 17. <% } %> 18. 19. <% foreach (ColumnSchema column in SourceTable.Columns) { %> 20. 21. public void set<%=column.Name.ToLower().ToPascalName() %> (<%= GetJavaType(column.DataType) + " "+column.Name.ToLower() %> ) { this.<%= column.Name.ToLower()+" = "+ column.Name.ToLower()%>; } 22. 23. public <%= GetJavaType(column.DataType) %> get<%=column.Name.ToLower().ToPascalName() %> () { return this.<%= column.Name.ToLower() %>;} 24. <% } %> 25.} 26. 27.<script runat="template"> 28./// <summary> 29. /// Java由Dbtype获得 的 Type 30. /// </summary> 31. /// <param name="dbtype"></param> 32. /// <returns></returns> 33. public static string GetJavaType(System.Data.DbType dbtype) 34. { 35. switch (dbtype) 36. { 37. case DbType.Int16: 38. case DbType.UInt16: 39. case DbType.Int32: 40. case DbType.UInt32: return "Integer"; 41. case DbType.Int64: 42. case DbType.UInt64: return "long"; 43. case DbType.Byte: return "Integer"; 44. case DbType.Date: 45. case DbType.DateTime: 46. case DbType.Datetime2: return "Date"; 47. case DbType.String: 48. case DbType.StringFixedLength: 49. case DbType.AnsiString: 50. case DbType.AnsiStringFixedLength: return "String"; 51. case DbType.Decimal: return "BigDecimal"; 52. case DbType.Double: 53. //case DbType.Currency: return "Double"; 54. case DbType.Currency: return "BigDecimal"; 55. default: return "String" ; 56. } 57. } 58.</script>
3. 转换数据类型
不同的目标语言离不开数据类型的转换,所以我们应该为不同的目标语言书写一种数据类型的转换方法。
例如,上述数据类型转换java类型的方法:
1.<script runat="template"> 2./// <summary> 3. /// Java由Dbtype获得 的 Type 4. /// </summary> 5. /// <param name="dbtype"></param> 6. /// <returns></returns> 7. public static string GetJavaType(System.Data.DbType dbtype) 8. { 9. switch (dbtype) 10. { 11. case DbType.Int16: 12. case DbType.UInt16: 13. case DbType.Int32: 14. case DbType.UInt32: return "Integer"; 15. case DbType.Int64: 16. case DbType.UInt64: return "long"; 17. case DbType.Byte: return "Integer"; 18. case DbType.Date: 19. case DbType.DateTime: 20. case DbType.Datetime2: return "Date"; 21. case DbType.String: 22. case DbType.StringFixedLength: 23. case DbType.AnsiString: 24. case DbType.AnsiStringFixedLength: return "String"; 25. case DbType.Decimal: return "BigDecimal"; 26. case DbType.Double: 27. //case DbType.Currency: return "Double"; 28. case DbType.Currency: return "BigDecimal"; 29. default: return "String" ; 30. } 31. } 32.</script>
我们的自定义方法可以在模板中书写,自定义方法可以使用<script runat="template">它可以在模板中调用
4. 如何提取公共方法
在开发过程中,我们不能只生成某种类型。例如,我们需要生成model、表格添加、删除和检查句子以及生成页面,但我们不能与数据类型的转换分开。因此,我们应该将公共代码提取到模板文件中,并在每个模板中引用该文件。方法如下:
新建模板文件,将公共方法剪切到模板文件中,包括在标签中,并在所需模板中引用模板,如:<%@ Register Template="../Reference/Extends.cst" Name="ExtendsTools" MergeProperties="True" %>
因此,我们的文件可以删除上面的GetJavaType方法。
外部也可以在模板中引用 c# 代码文件,<%@ Assembly Src="../Reference/SqlScriptExtend.cs" %>
外部程序集也可以在模板中引用 <%@ Assembly Name="CodeSmithExtend" Path="../Reference" %>引入的代码方法也可以在模板中调用。
在我们编译完模板之后,模板就可以使用了,生成的代码流程图如下:经验分享
在实际使用中,我们不仅可以生成来源单表的代码,还可以写支持sql。
1.首先,在模板上注册两个控件
2.<%@ Property Name="QuerySqlScript" Type="StringCollection" Editor="StringCollectionEditor" Category=“数据源配置” Description=“查询sql” Optional="True" OnChanged="QuerySqlScriptChange" %>
3.<%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" Category=“数据源配置” Optional="True" Description=该数据库连接需要在SQL查询中配置数据源,为了生成查询列” %>
为QuerySqlScript控件注册变更事件QuerySqlScriptchangenge
在这个事件中,我们使用注册数据源执行我们输入的sql,以返回table结果。我们只需要关注列名,然后用正则表达式从sql中匹配表名,再次用数据源查询sql中涉及的表结构。这时,我们从获得的表结构中提取了一个tabletableschema。 对象中,然后我们就可以继续在模板中使用这个TableSchema了 生成代码。
总结
如果使用Codesmith代码生成相同的代码,可以减少70%的工作量 model的生成,sql脚本的表增删,基本页面的生成,wiki的生成。
假如标准制定好了,甚至可以达到不写一行代码的目的。
代码生成也可以直接输出到文件中。
- 官网地址 https://www.codesmithtools.com/
作者|李丙龙
作者:古道轻风