代码生成器作用

中国有句古语叫做“工欲善其事,必先利其器”,用通俗的话来说就是“磨刀不误砍柴功”,古人的这些话告诉我们:要把事情做好,事先应该准备合适的工具。工具不仅仅包括器具,

还包括思想、理论、经验、道德、法律等一切能解决问题的有形和无形的东西。

CodeSmith介绍

CodeSmith是一个代码生成器,可以用来大量生成代码的。用起来其实也很简单,可是许多人都不能入门。大部分的代码生成工具都是需要模板的,这个很好理解,模板就是一段代码,

里面留几个洞,这个洞会被数据库的字段名或表名等填充,CodeSmith的最多的用法就是连接数据库,然后把数据库信息取出来去替换用户提供的模板中关键字,这就是代码生成的原理。

为了生成更灵活,模板和关键字可以混合在一起写,这个蛮怪异的,不过你看懂了也就无所谓了。

当生成应用程序时,无论是编写数据访问代码还是生成自定义集合,你会发现经常需要重复完成某些特定的任务。这时 CodeSmith 就显得特别有用,因为你可以编写模板自动完成

这些任务,从而不仅提高你的工作效率,而且能够自动完成那些最为乏味的任务。

CodeSmith界面

CodeSmith 的代码编写界面跟常见的开发IDE很类似。常用的就是Bulid Templete, Generate,以及Output  VIEW。

CodeSmith 语法介绍

  1. .注释
  2.  
  3. <%-- 这是一个C#语言的模板 --%>
  4.  
  5. .加载使用访问数据库的组件SchemaExplorer,并声明其使用的命名空间
  6.  
  7. <%@ Assembly Name="SchemaExplorer" %>
  8. <%@ Import Namespace="SchemaExplorer" %>
  9.  
  10. .声明表对象
  11.  
  12. <%@ Property Name="TargetTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="TargetTable that the object is based on." %>
  13.  
  14. .声明视图对象
  15.  
  16. <%@ Property Name="TargetView" Type="SchemaExplorer.ViewSchema" Category="Context" Description="TargetView that the object is based on." %>
  17.  
  18. .设置输入信息框
  19. <%@ Property Name="Author" Type="String" Category="Context" Description="作者" %>
  20.  
  21. .编写C# 语言块
  22.  
  23. 5.1 <% %>
  24. 5.2 <script runat="template">
  25. private string GetDesc(string name)
  26. {
  27. string temp=string.Empty;
  28. temp+="//作者:"+name+" Create Date:"+System.DateTime.Now.ToString();
  29. return temp;
  30. }
  31. </script>
  32. 5.3 创建.cs文件,声明中src 引用
  33. <%@ CodeTemplate Language="C#" TargetLanguage="C#" Src="Common.cs" Description="指明是一个C#语言版本" Inherits="Common" %>
  34.  
  35. .赋值<%= %>
  36.  
  37. .相关的数据库对象
  38. 7.1 表名:TargetTable.Name
  39. 7.2 表列结合:TargetTable.Columns
  40. 7.3 列描述:column.Description

CodeSmith 生成实体类模板

有了上述的语法知识,我们开始编写一个简单的实体对象(Model),最终结果是

  1. //============================================================
  2. ///Create By:QingQing
  3. //============================================================
  4.  
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Text;
  8.  
  9. namespace POP.Domain
  10. {
  11. [Serializable()]
  12. public class Area
  13. {
  14. /// <summary>
  15. ///
  16. /// </summary>
  17. public long Areaid {get;set;}
  18. /// <summary>
  19. ///
  20. /// </summary>
  21. public string Areaname {get;set;}
  22. /// <summary>
  23. ///
  24. /// </summary>
  25. public string Aliasname {get;set;}
  26. /// <summary>
  27. ///
  28. /// </summary>
  29. public long? Parentid {get;set;}
  30. /// <summary>
  31. ///
  32. /// </summary>
  33. public long? Sortno {get;set;}
  34. /// <summary>
  35. /// T:有效,F:无效
  36. /// </summary>
  37. public string Valid {get;set;}
  38. }
  39. }

思考一下,using 引用的命名空间是固定的,get set熟悉是固定的,剩下的就是要从数据库里获取表对象进行填充了,上模板。

  1. <%-- 这是一个C#语言的模板 --%>
  2. <%@ CodeTemplate Language="C#" TargetLanguage="C#" Src="Common.cs" Description="指明是一个C#语言版本" Inherits="Common" %>
  3. <%-- 加载使用访问数据库的组件SchemaExplorer,并声明其使用的命名空间 --%>
  4. <%@ Assembly Name="SchemaExplorer" %>
  5. <%@ Import Namespace="SchemaExplorer" %>
  6. <%-- 通过这个数据表类型的变量得到相应的表的信息:TableSchema(表) ViewSchema(视图) --%>
  7. <%@ Property Name="TargetTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="TargetTable that the object is based on." %>
  8. <%@ Property Name="Author" Type="String" Category="Context" Description="作者" %>
  9. <%--代码需要的输入值变量--%>
  10. <%@ Property Name="NameSpace" Default="MyTest.DoMain" Type="String" Category="Context" Description="生成代码是需要输入的变量" %>
  11.  
  12. <%--<%=GetDesc(Author)%>--%>
  13. <% PrintHeader(Author); %>
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Text;
  17.  
  18. namespace <%=NameSpace %>
  19. {
  20. [Serializable()]
  21. public class <%=GetNewTableName(TargetTable.Name)%>
  22. {
  23. <%
  24. foreach (ColumnSchema column in TargetTable.Columns)
  25. {
  26. %>
  27. /// <summary>
  28. /// <%=column.Description %>
  29. /// </summary>
  30. public <%=GetCSharpTypeFromDBFieldType(column) %> <%=GetNewColoumName(column.Name)%> {get;set;}
  31. <%
  32. }
  33. %>
  34. }
  35. }
  36.  
  37. <script runat="template">
  38. /// <summary>
  39. ///// 设置文件描述
  40. /// </summary>
  41. /// <param name="name"></param>
  42. /// <returns></returns>
  43. private string GetDesc(string name)
  44. {
  45. string temp=string.Empty;
  46. temp+="//作者:"+name+" Create Date:" +System.DateTime.Now.ToString();
  47. return temp;
  48. }
  49.  
  50. /// <summary>
  51. /// 设置文件名称,后缀名
  52. /// </summary>
  53. /// <returns></returns>
  54. public override string GetFileName()
  55. {
  56. return this.TargetTable + ".cs";
  57. }
  58. </script>

编译模板

模板编写完成,要进行编译,确认语法是否通过。输出日志框,错误列表都是我们的好帮手。

使用模板生成文件

OK,模板编译通过我们就要见证奇迹的时刻了。

批量生成文件

单个文件能够生成了,是不是很方便呢,但是聪明的你肯定发现,怎没有提供批量生成的按钮呢?对的,这就需要我们继续编写模板来进行实现了。

批量生成要注意一下几点:

  1. 注册生成单个模板的文件
  2. 添加单个文件需要使用的文本框
  3. 注册获取数据库的对象
  4. 编写方法遍历数据库的表对象
  5. 编写获取输出文件的路径

    以下就是模板,同样的右键点击模板,Execute,填写相关参数,选择数据库,Generate,生成的文件就会出现在选择的文件夹中

  1. <%@ CodeTemplate Inherits="CodeTemplate" Language="C#" TargetLanguage="Text" Description="生成整个表" Debug="True" ResponseEncoding="UTF-8"%>
  2.  
  3. <%-- 注册实体层Entity模板 --%>
  4. <%@ Register Name="EntityTemplate" Template="BaseForModel.cst" MergeProperties="Flase" ExcludeProperties=""%>
  5. <%@ Property Name="Author" Type="String" Category="02.作者" Description="作者" %>
  6. <%-- 获取整个数据库对象 --%>
  7. <%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" DeepLoad="True" Optional="False" Category="01. 获取数据库对象" Description="获取整个数据库对象"%>
  8.  
  9. <%
  10. //创建实体层Entity类
  11. this.GenerateEntityClasses();
  12. //Debug模式下的信息[Debug="True"]
  13. Debug.WriteLine("Success");
  14. %>
  15.  
  16. <script runat="template">
  17. //生成实体Entity类
  18. private void GenerateEntityClasses()
  19. {
  20. //获取模板对象
  21. CodeTemplate Template =new EntityTemplate();
  22. foreach(TableSchema table in this.SourceDatabase.Tables)
  23. {
  24. string FileDirectory = OutputDirectory +"\\"+ GetNewTableName(table.Name) +".cs";
  25. //设置模板的相关内容(Table名称 ,作者名称)
  26. Template.SetProperty("TargetTable",table);
  27. Template.SetProperty("Author",Author);
  28. //文件输出
  29. Template.RenderToFile(FileDirectory,true);
  30. Debug.WriteLine(FileDirectory +" 创建成功.");
  31. }
  32. }
  33.  
  34. /// <summary>
  35. /// 获取新的TableName(首字母大写,去掉下划线)
  36. /// </summary>
  37. /// <param name="name"></param>
  38. /// <returns></returns>
  39. public string GetNewTableName(string name)
  40. {
  41. string table=name.Substring().ToLower();
  42. string tempTableName=string.Empty;
  43. if(table.IndexOf('_')>)
  44. {
  45. string[] temp=table.Split('_');
  46. for (int i = ; i < temp.Length; i++)
  47. {
  48. tempTableName+=System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(temp[i]); //设置首字母大写
  49. }
  50. }
  51. else
  52. {
  53. tempTableName=System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(table); //设置首字母大写
  54. }
  55. return tempTableName;
  56. }
  57.  
  58. //解决方案输出路径
  59. private string Directory = String.Empty;
  60.  
  61. [Editor(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
  62. [Optional, NotChecked]
  63. [DefaultValue("")]
  64. public string OutputDirectory
  65. {
  66. get
  67. {
  68. return Directory;
  69. }
  70. set
  71. {
  72. if (value.EndsWith("\\")) value = value.Substring(, value.Length -);
  73. Directory = value;
  74. }
  75. }
  76. </script>

总结

CodeSmith  最大的优势就是编写模板生成符合条件的代码。其IDE自身提供了很多相关的模板,里面有很多好用的语法糖。附件提供自己编写的几个模板,供大家学习参考。

小伙伴们快快动手编写属于自己的模板吧,从繁琐的任务重脱离出来,我们的编程更加的愉快。

下载

CodeSmith 介绍的更多相关文章

  1. CodeSmith介绍和常见问题解决方案

    一.CodeSmith介绍 CodeSmith模板代码生成实战详解  https://www.cnblogs.com/knowledgesea/p/5016077.html 二.CodeSmith连接 ...

  2. 常用工具&网址

    工具 I tell you http://www.win7999.com/news/197912345.html VisualSVN Server(免费) http://www.visualsvn.c ...

  3. CodeSmith中SchemaExplorer属性的介绍

    CodeSmith与数据库的联系,在CodeSmith中自带一个程序集SchemaExplorer.dll,这个程序集中的类主要用于获取数据库中各种对象的结构. <%@ Property Nam ...

  4. CodeSmith模板代码生成实战详解

    前言 公司项目是基于soa面向服务的架构思想开发的,项目分解众多子项目是必然的.然而子项目的架子结构种类也过多的话,就会对后期的开发维护产生一锅粥的感觉.为了尽可能的在结构层避免出现这种混乱的现象,我 ...

  5. 应用程序框架实战三十六:CRUD实战演练介绍

    从本篇开始,本系列将进入实战演练阶段. 前面主要介绍了一些应用程序框架的概念和基类,本来想把所有概念介绍完,再把框架内部实现都讲完了,再进入实战,这样可以让初学者基础牢靠.不过我的精力很有限,文章进度 ...

  6. 应用程序框架实战二十九:Util Demo介绍

    上文介绍了我选择EasyUi作为前端框架的原因,并发放了最新Demo.本文将对这个Demo进行一些介绍,以方便你能够顺利运行起来. 这个Demo运行起来以后,是EasyUi的一个简单CRUD操作,数据 ...

  7. 软件代码生成之Codesmith模板.netTiers

              .netTiers模板到2006年就诞生了, 到今天最后一次更新是12/17/2013, 支持.NET 4.5 and Visual Studio 2012 and 2013. n ...

  8. [转]CodeSmith和PowerDesigner的使用安装和数据库创建

    最近要忙期考,但还是决定每天抽点空来写CodeSmith的系列文章了,在此实在不敢用教程这个词语,毕竟自己对CodeSmith了解的也不是很多,有很多牛人都在博客园发布了不少关于CodeSmith的文 ...

  9. 是时候改变你的开发方式了-XAF信息系统快速框架介绍

    我是一名.Net开发者,从DOS时代Turbo c 算起(1996年),马上满20年了.想想写过的代码真是不少,却做了很多重复反复的编码工作.当然中间也带过团队做过几个大项目,但是代码仍没写够,还是每 ...

随机推荐

  1. 2016huasacm暑假集训训练四 递推_B

    题目链接:http://acm.hust.edu.cn/vjudge/contest/125308#problem/B 题意:给定n个三角形,问最多可以把区域化成多少个部分,这是一个一维空间  一定会 ...

  2. 重学ps_1

    1,选取 打开图片->点击选取工具->ctrl+c->ctrl+n->ctrl+v 2,去除图片背景 打开你要去除背景的图片->在图层面板中->双击图层把图层改为0 ...

  3. FAT32文件系统

  4. CSS 学习笔记

    0.CSS概念层叠样式表(Cascading Style Sheets),CSS的来历就不必多说了.可以简单的理解为万维网联盟(w3c)为了丰富HTML页面的布局和外观而指定的一种标准. 1.CSS实 ...

  5. Unity透明材质Batch

    NO Batch  ? 游戏场景中存在大量例子的时候,DrallCall的压力很大,但是遍历一遍之后发现,为啥一样的粒子特效竟然没有合并,why?经过很多测试后发现,如果把透明材质的修改为非半透明的, ...

  6. Shell 重定向

    一直没搞懂 &> 和 <& 是表示什么意思. 今天自己总结一下,希望自己能理解它的真正含义. 重定向标准输入输出,切记 “1” 和 “>”之间没有空格 $ > ...

  7. windows平台 查看 dll 程序集 PublicKeyToken

    打开Developer Command Prompt for VS20** 命令工具 路径:点击开始->所有程序->Microsoft Visual Studio 20** ->Vi ...

  8. 解决Rational Rose 中 没有 Data modeler 选项的问题

    在  Rose  没有 Data modeler 选项的原因是没有将 Data modeler 这块功能勾选上. 解决方案: 菜单栏--Add-Ins--Add-Ins Manager-->找到 ...

  9. blowfish ECB decode

    blowfish  ECB  Decode package main import ( "crypto/cipher" "encoding/hex" " ...

  10. Q的深层嵌套

    1.如果将异步方法用同步的方式执行,try catch能捕获到错误,同时不会阻塞到主进程,因此console.log(3333)能执行. var fs = require('fs'); try { v ...