创建代码生成器可以很简单:如何通过T4模板生成代码?[下篇]
但是这是一种基于单个文件的解决方案,即我们必须为每一个生成的存储过程建立一个模板。如果我们提供一种基于多文件的代码生成方式,将会为编程人员带来极大的便利。借助于T4 ToolBox这个开源工具箱,多文件的SQL Generator的实现变得异常简单。[文中的例子可以从这里下载]目录 二、创建自定义的Generator 三、ProcedureGenerator如何被使用?一、多文件代码生成器会带来多大的便利?我们先来直观的感受一下较之《上篇》提供的单一文件的代码生成器,基于多文件的代码生成解决方案会为开发人员带来多大的便利。 同样对于《上篇》创建的数据表T_PRODUCT,之前我们为了生成三个不同的存储过程,我们不得已需要创建3个不同的T4模板文件。实际上我们更需要的方式只需要创建一个T4模板,让我们的SQL Generator自动为我们生成3个包含相应存储过程的.sql附属文件,如左图所示(点击看大图)。有的时候,基于单个数据表的存储过程生成方式我们依然觉得不方便。如果我们能够在T4模板文件中指定的数据表的列表,让我们的SQL Generator为列表的每一个数据表都生成CUD三个存储过程,这样的方式更加具有吸引力。如右图所示(点击看大图),一个订单模块包含两个具有主子关系的两张表(T_ORDER和T_ORDER_DETAIL),现在我们在一个T4模板中指定这两个表明,通过SQL Generator可以帮助我们生成6个包含存储过程的.sql附属文件。甚至有的时候我们连数据表列表都无需指定,让SQL Generator为所有的表都生成相应的存储过程。我的例子中没有提供这样的功能,但是实现自来不会存在任何问题。二、创建自定义的Generator在《上篇》中我创建了一个抽象的ProcedureTemplate类,以及三个基于生成CUD存储过程的具体ProcedureTemplate:InsertProcedureTemplate、UpdateProcedureTemplate和DeleteProcedureTemplate。它们都将直接服务于我们今天将要提供的基于多文件的SQL Generator。在《上篇》中,这四个Template分别定义在4个不同的TT文件中,3个具体的ProcedureTemplate通过#@include指令将抽象ProcedureTemplate模板文件包含过来。由于我们将要创建的T4模板将会使用到这四个类,如果我们用四个#@include指令将四个TT文件包含过来,由于T4引擎将会导致对ProcedureTemplate的4次包含,最好将会导致变异问题。个人觉得这应该算是T4引擎解析包含关系的一个局限性,为了解决这个问题我们不得不抽象的ProcedureTemplate和三个具体的ProcedureTemplate都合并成一个TT文件。T4 ToolBox为类库中为了提供了一个抽象的T4Toolbox.Generator类用于实现多文件的代码生成。为此我们创建一个TT模板文件,定义了如下一个继承自该类的ProcedureGenerator。ProcedureGenerator的核心是通过属性Templates定义的类型为IEnumerableProcedureTemplate的ProcedureTemplate列表,这个列表在存储过程中进行初始化。而对于ProcedureGenerator的构造函数,处理定义了一个表示数据库连接字符串的databaseName的参数外,并以数组参数的形式指定了生成的存储过程基于的数据表名的列表。#@ import namespace="System.Collections.Generic" ##@ include file="ProcedureTemplate.tt" ##@ include file="T4Toolbox.tt" ##+publicclass ProcedureGenerator : Generator{public IEnumerableProcedureTemplate Templates{get; private set;}public ProcedureGenerator(string databaseName, paramsstring[] tableNames) {if(null == tableNames || tableNames.Length == 0) {thrownew ArgumentNullException("tableNames"); } this.Templates = InitlizeTemplates(databaseName,tableNames); }private IEnumerableProcedureTemplate InitlizeTemplates(string databaseName, string[] tableNames) { foreach(string tableName in tableNames) {yieldreturnnew InsertProcedureTemplate(databaseName, tableName);yieldreturnnew UpdateProcedureTemplate(databaseName, tableName);yieldreturnnew DeleteProcedureTemplate(databaseName, tableName); } }protectedoverridevoid RunCore() {foreach(ProcedureTemplate tempalte inthis.Templates) { tempalte.RenderToFile(tempalte.GetProcedureName() + ".sql"); } }}#真正的存储过程的T-SQL脚本实现在重写的RunCore中。由于具体的文本转化逻辑都定义在了ProcedureTemplate中了,所以在这里我们需要遍历的ProcedureTemplate集合中每一个Template对象,调用RenderToFile方法将相应的存储过程的脚本写入以存储过程命名同名的.sql文件中。三、ProcedureGenerator如何被使用?我们最后来看看我们创建的ProcedureGenerator最终如何被应用于具体的代码生成。其实很简单,我们只需要创建相应的模板文件,通过#@include将定义ProcedureGenerator类的TT文件包含近来,最后以代码语句调用块(#StatementCode#)的形式实力化该对象,并调用Run方法即可。在构造函数中指定数据库连接字符串的名称和数据表名的列表。下面是基于但表的T4模板。#@ template language="C#" hostSpecific="true" debug="true" ##@ include file="Templates\ProcedureGenerator.tt" ##new ProcedureGenerator("TestDb","T_PRODUCT").Run();#下面是基于多表的T4模板:#@ template language="C#" hostSpecific="true" debug="true" ##@ include file="Templates\ProcedureGenerator.tt" ##new ProcedureGenerator("TestDb","T_ORDER","T_ORDER_DETAIL").Run();#当你代码生成工作执行之后,会多出一个与TT文件同名的附属文件,你需要手工删除掉它。从数据到代码——通过代码生成机制实现强类型编程[上篇]从数据到代码——通过代码生成机制实现强类型编程[下篇]从数据到代码——基于T4的代码生成方式
动软代码生成器生成的代码怎么用
动软代码生成器 是一款为程序员设计的全功能自动代码生成器,也是一个智能化软件开发平台,它可以生成基于面向对象的思想和三层架构设计的代码,结合了软件开发中经典的思想和设计模式,融入了工厂模式,反射机制等等一些思想。主要实现在对应数据库中表的基类代码的自动生成,包括生成属性、添加、修改、删除、查询、存在性、Model类构造等基础代码片断,支持不同架构代码生成,使程序员可以节省大量机械录入的时间和重复劳动,而将精力集中于核心业务逻辑的开发。新版本中除了程序集组件模板,也同样支持用户自定义文本模板,像写ASPX代码一样写模板,一键代码生成,更方便,更灵活。
动软让软件开发变得轻松而快乐!让企业不断提升开发效率,同样的时间创造出更大的价值。
如何用动软代码生成器自定义
1
打开工具,点击如下图的连接SQL Server数据库服务器;
2
如图,填写好数据库相关配置,点击连接测试,可以看到你的数据库出现在了下拉列表中,点击选择你的数据库,点击下一步;
3
如图,选择要生成代码的数据库;
4
填写项目解决方案的名称和存储位置的信息;
5
选择要生成代码的表,选择你需要的模板,如图,根据需求填写;
6
点击开始生成,生成好了一个.NET的解决方案,里面的必要的代码已经自动生成好;
怎么让代码生成器生成的代码自动对齐
工具/原料
动软代码生成器2.78
SQL Server 2005/2008
Visual Studio 2008/2010或更高版本
方法/步骤
1
下载
1. 系统要求:Microsoft Windows2000/XP/2003/7 或者更高。机器必须安装.NET Framework v2.0。
2. 官方下载地址:http://www.maticsoft.com/download.aspx
3. 下载解压后安装包有如下文件,如图:
Codematic2.msi 是动软.NET代码生成器的安装文件。
Builder文件夹是代码生成插件的源码,动软.NET代码生成器支持可扩展的代码生成插件,用户可以定制自己的代码生成的插件,根据接口开发自己的代码生成方式,按自己的需求进行代码生成。
Codematic_Data.MDF和Codematic_Log.LDF是通过动软新建项目中所带管理模块所需要的数据库文件。后台管理员默认登录用户名:admin 密码:1
2
安装
1.双击Codematic2.msi 进行直接安装即可。安装动软时,如果用户机器360弹出警告,那仅仅是个签名认证提示,并非木马,选择“继续安装”,然后点击“确定”即可。
2.安装成功后,在开始-菜单和桌面上会有动软.NET代码生成器的图标。
3
在软件界面的左侧数据库视图窗口,选择【服务器】,右键出现菜单或 点击第1个按钮如图红框内
4
选择【添加服务器】,然后,出现“选择数据库类型”窗口
5
根据自己的实际情况,选择一个机器上有的或自己项目中在用的数据库类型。并确保你选择的数据库是可以正常访问的。然后,【下一步】。
如果选择的是SQL Server,则会出现如图所示界面:
注意事项:
(1) 输入服务器IP地址,如果是本机也可以是:(local) 或是. 或者 127.0.0.1。 如果服务器并非只有一个默认实例,请采用:服务器\实例名的方式连接。(2)一定要选择和实际数据库服务器版本一致的选项,否则会导致连接数据库错误。注意:请使用SQLServer的企业版或正式版本,不能是SQL EXPRESS版,否则无法连接。(3)身份验证可以选择是SQLServer认证,还是Windows认证。
(4)输入数据库服务器用户名密码。如果不知道,请联系你的数据库管理员。(5)如果数据库的表比较多,连接速度会比较慢,启用【高效连接模式】实现快速连接。(6)可以通过【连接/测试】,来连接服务器并获取数据库列表,从而可以实现只选择连接一个库进行操作,减少不必要的连接时间,提高工作效率。
6
如果选择的是Oracle,出现如图所示界面;
输入您自己安装过的Oracle的管理员用户名和密码,服务就是安装的Oracle服务名,一般默认是Oracle所在的机器名,如果不确定,请联系您的数据库管理员。
7
如果选择的是MySQL,出现如图所示界面
8
如果选择的是Oledb出现如图所示界面;
在地址文本框,可以直接输入Access库的文件地址,注意:库文件尽量不要放在桌面,并且确保你的文件地址正确。如果你的Access并没有设置密码,下面的密码可以不用管。
9
如果选择的是SQLite,出现如图所示界面
10
在以上步骤确定后,动软.NET代码生成器的数据库视图就出现了数据库服务器的信息。如图所示
11
在数据库上右键,【浏览数据库】,通过选择库和表可以查看表和字段的信息。
12
选择【新建查询】菜单,即出现SQL的查询分析器窗口,可以输入SQL语句进行查询。
13
在表上,右键选择【浏览表数据】,可以查看表的数据内容。
14
新建整个项目
在看过了基本的数据库管理功能之外,下面我们就可以开始生成代码了。
首先,一般第一次生成,我们要生成的是整个项目框架。
选中数据库,然后右键:【新建NET项目】,或者直接点工具栏上的快捷图标均可。
15
然后,选择项目类型和版本:如图所示;
l 简单三层结构:生成标准的三层架构项目。
l 工厂模式结构:生成基于工厂模式的项目架构,适合一个项目多数据库类型的情况。
l 简单三层结构(管理):生成标准的三层架构项目,并且带有基本的系统管理功能和界面,这些通用的功能主要是节省开发人员的时间,可以在此基础上直接去开发自身业务模块。
这里暂以“简单三层结构(管理)”为例进行说明。
16
点击【下一步】,选择要生成的表和配置:如图所示;
双击选择要生成的表,选到右侧列表框。然后点击【开始生成】即可。
如果需要修改一些配置可以修改你自己的命名空间名字,是否去掉表的前缀。
代码模板组件类型,一般初学者建议默认即可。
相关组件说明:
BuilderDALParam 数据访问层(DAL)基于Parameter方式的代码生成组件(推荐)
BuilderDALProc 数据访问层(DAL)基于存储过程方式的代码生成组件
BuilderDALSQL 数据访问层(DAL)基于SQL拼接方式的代码生成组件
BuilderDALTranParam 数据访问层(DAL)带有事务的代码生成组件
DAL由于不同项目要求不同,根据项目需求,选择其中一种方式即可。
BuilderBLLComm 基于标准的业务逻辑层代码(BLL)
BuilderModel Model层的代码生成组件
BuilderWeb 表示层的代码生成组件
备注:代码还有一些生成规则,是在菜单【工具】-【选项】-【代码生成设置】中进行设置。
17
点击【开始生成】,则开始进行代码的生成,直到出现“项目工程生成成功”提示,项目生成完毕,如图所示;
18
打开生成的文件夹,如图所示;
19
双击解决方案文件,打开整个项目如图所示;
注:“简单三层结构”目前暂时是VS2005版本,是为了兼容当前还在用2005的朋友。如果你使用的是VS2008,生成项目后,请先打开VS2008,选择【菜单-文件-打开项目】的方式打开该项目,此时会提示升级项目版本,选择升级一下项目版本到VS2008或VS2010即可,对代码没有任何影响。
20
打开Web项目,选中刚才选择生成的那几个表的页面文件夹,右键【包括在项目中】,如图所示;
21
打开web项目下web.config修改数据库连接字符串,如图所示;
注意:新建项目后,请记得先将安装包里附带的数据库文件Codematic_Data.MDF 附加到SQLServer中。
如果需要加密,可以使用安装包里的加解密工具(官方下载该工具)。
然后,选择解决方案进行重新生成整个解决方案。整个创建项目过程即全部完成。如图所示;
如果编译没有错误, 直接按F5键运行即可。整个创建项目过程即全部完成。
运行启动登录页面login.aspx,输入用户名:admin,密码:1
即登录动软系统框架的后台,界面如下
批量代码生成
新建项目功能只适合于第一次,因为不可能每次都新建项目,特别是项目已经在开发中。所以,以后的项目开发中更多的应用的是【批量代码生成】功能。批量代码生成特别适合项目后期追加代码时使用。
选中数据库或者表,然后单击右键菜单【代码批量生成】,如图所示;
出现的窗口和新建项目基本相似,只是多了一个选中架构的选项。如图所示;
备注:代码还有一些生成规则,是在菜单【工具】-【选项】-【代码生成设置】中进行设置。
选则要生成的表,然后点击【导出】
在生成的文件夹中,我们可以看到:如图所示
批量生成代码只生成业务表的代码,不再有解决方案文件和项目文件,以及其它类库等。我们可以将生成的这些文件直接拖到现有的解决方案中即可。
单表代码生成
除了新建项目和批量代码生成,偶尔我们希望更个性化自定义一些代码生成的字段,而不是全部的自动生成,这是我们可以考虑针对单表的代码生成。
在左侧【数据库视图】,选中表,右键菜单【单表代码生成器】,如图所示
然后,出现单表的代码生成器界面,我们设置自己需要更改的信息。如图所示;
选项说明:
Ø 项目名称:主要用在生成DB脚本中。
Ø 二级命名空间:指的是这个类放在某一个二级文件夹下,从而命名空间中应该带这个文件夹的名字。
Ø 顶级命名空间:就是项目的命名空间名称。
Ø 类名:可以自己根据表名定义自己需要的名字。
Ø 类型:主要是生成什么代码,DB脚本主要生成表的存储过程和表的创建脚本及数据脚本。
Ø 架构选择:目前仅支持这3种最常用的架构。
Ø 代码类型:指生成指定架构中具体某一个项目中的代码。
Ø 代码模板组件类型:指生成代码的方式,因为即使同一个代码有很多的写法,组件主要实现的是不同的写法,但每种写法实现的功能都是一样的。主要看项目需要和个人习惯进行选择。
Ø 方法选择:指生成最基本的增删改查的方法代码,后续版本将支持用户自定义这些方法。
备注:代码还有一些生成规则,是在菜单【工具】-【选项】-【代码生成设置】中进行设置。
然后,点击【生成代码】按钮,即可生成该类的代码,如图所示;
生成的代码,可以直接复制到项目文件中,也可以右键保存成CS文件。
通过窗体下面的Tab按钮可以来回切换设计视图和代码。
代码生成规则设置
打开菜单【工具】-【选项】-【代码生成设置】
这些配置保存后,在生成代码的时候将按照这个规则进行生成。
代码生成的规则设置范围还在不断增加中。
另外,不同数据库类型的数据类型各有不同,这里提供了字段类型和C#中的类型建立映射关系,生成代码时将按映射关系来生成代码字段属性的类型。
如何:自定义对象层代码生成(实体数据模型设计器)
默认情况下,实体设计器使用 EntityModelCodeGenerator 自定义工具生成对象层代码(有关更多信息,请参见生成的代码概述(实体数据模型设计器))。向项目添加文本模板时,实体设计器可以使用该模板生成对象层代码,而不使用默认的自定义工具。注意:您可以搭配使用命令行工具和文本模板生成对象层代码。有关更多信息,请参见文本模板的命令行工具(可能为英文网页)。Visual Studio 提供两个用于生成实体框架对象层代码的 ADO.NET 模板:“ADO.NET EntityObject 生成器”和“ADO.NET 自跟踪实体生成器”。“ADO.NET EntityObject 生成器”生成的代码与 EntityModelCodeGenerator 自定义工具生成的代码相同。“ADO.NET 自跟踪实体生成器”模板生成包含自跟踪状态逻辑的实体类。使用N 层应用程序时使用自跟踪实体。有关ADO.NET 模板的更多信息,请参见 ADO.NET EntityObject 生成器模板和ADO.NET 自跟踪实体生成器模板。以下过程假定:您在Visual Studio 2010 中打开了面向 .NET Framework 4 的 Visual Basic 或 C# 项目。您使用实体设计器打开了 .edmx 文件。您熟悉如何自定义文本模板。有关文本模板的信息,请参见生成项目(可能为英文网页)。自定义对象层代码生成右击实体设计器图面的空白区域,指向“添加代码生成项”,然后选择可用的模板。如果没有显示任何可用的模板,则在“已安装的模板”窗格中选择“代码”。代码生成项将向项目添加一个或多个文本模板 (.tt) 文件。文本模板将生成对象层代码。在.tt 文件下添加生成的文件。如果不修改此模板,生成的代码将与实体设计器生成的代码相同。向项目添加文本模板时,Visual Studio 执行以下操作:将概念模型的“代码生成策略”属性设置为“无”。这将关闭默认代码生成。在.edmx 文件所在的目录中向项目添加新文本模板文件。将相对于文本模板的 .edmx 文件路径插入到文本模板。这样做的目的是为了确保该文本模板处理的是正确的 .edmx 文件。基于.edmx 文件使用文本模板生成代码。生成的代码将写入 text_template_name.cs 或text_template_name.vb 文件中。此代码文件将作为该模板文件的依赖文件添加在“解决方案资源管理器”中。打开文本模板并进行编辑。保存编辑后的文本模板文件。在保存该文本模板文件时,会根据编辑后的文本模板文件重新生成对象层代码。默认情况下,只要保存 .edmx 文件,就会触发 .edmx 文件的对象层代码生成操作。不保留对 text_template_name.cs 或text_template_name.vb 代码文件所做的任何手动更改。如果一个 .edmx 文件有多个文本模板文件与其关联,则保存 .edmx 文件时会重新生成所有关联的代码文件。但是,可以更改这种行为。如果将概念模型的“保存时转换相关的文本模板”属性设置为 false,保存文件时将不会重新生成代码文件。在将模型和 .tt 文件拆分成单独的项目时,只要修改了 .edmx 文件或 .tt 文件就应手动运行代码生成。通过单击解决方案资源管理器中的“转换所有模板”按钮可执行此操作。
如何在VisualStudio中开发自己的代码生成器插件
用Visual Studio 2012创建名为MyVisualStudioAddin的项目(根据向导进行设置,这里不赘述),界面如下:
核心 Connect 类
插件入口就是Connect 类,先看一下Connect的类图:
Connect 实现外接程序对象的构造函数。请将您的初始化代码置于此方法内。
OnConnection 实现 IDTExtensibility2 接口的 OnConnection 方法。接收正在加载外接程序的通知。
OnDisconnection 实现 IDTExtensibility2 接口的 OnDisconnection 方法。接收正在卸载外接程序的通知。
OnAddInsUpdate 实现 IDTExtensibility2 接口的 OnAddInsUpdate 方法。当外接程序集合已发生更改时接收通知。
OnStartupComplete 实现 IDTExtensibility2 接口的 OnStartupComplete 方法。接收宿主应用程序已完成加载的通知。
OnBeginShutdown 实现 IDTExtensibility2 接口的 OnBeginShutdown 方法。接收正在卸载宿主应用程序的通知。
QueryStatus 实现 IDTCommandTarget 接口的 QueryStatus 方法。此方法在更新该命令的可用性时调用。
Exec 实现 IDTCommandTarget 接口的 Exec 方法。此方法在调用该命令时调用。
_applicationObject 是DTE2实例,是宿主应用程序的根对象。
_addInInstance是当前插件实例,表示此外接程序的对象。
首先定义一些内部的对象,主要是自定义的命令,如下所示:
1 /// summary用于实现外接程序的对象。/summary 2 /// seealso class='5ac3-1bce-c311-56ad IDTExtensibility2' / 3 public class Connect : IDTExtensibility2, IDTCommandTarget 4 { 5 #region 命令定义 除了FindInSolutionExplorer外,此处的命令不是根据功能来命令的,而是根据命令所出现的位置来命令的 6 private readonly string MY_COMMAND_FindInSolutionExplorer = "FindInSolutionExplorer"; 7 private readonly string MY_COMMAND_Project = "cmdInProject";//在项目上 8 private readonly string MY_COMMAND_Solution = "cmdInSolution";//在解决方案上 9 private readonly string MY_COMMAND_MenuBar = "cmdInMenuBar";//在菜单栏上10 private readonly string MY_COMMAND_CodeWindow = "cmdInCodeWindow";//代码窗口11 private readonly string MY_COMMAND_Files = "cmdInFiles";12 #endregion13 14 private Command findCommand = null;15 private CommandBarButton findCommandBarButtonButton = null;16 private AddInLogger logger = null;17 18 private DTE2 _applicationObject;19 private EnvDTE.AddIn _addInInstance;20 ......21 }
如何生成使用自定义活动的代码
在工作流编译期间,将调用 GenerateCode,它允许向编译器生成的工作流分部类添加其他代码。在将它传递给 C# 编译器之前,必须以 CodeDOM 形式对其进行重写。 在可以实时生成代理类的 Web 服务活动中,或者在活动需要基于它在运行时使用的配置发出代码的其他情况下,此方案将十分有用。下面的示例演示如何为自定义活动生成代码。public override void GenerateCode(CodeGenerationManager manager, object obj) { if (manager == null) { throw new ArgumentNullException("The CodeGenerationManager object is null."); } if (obj == null) { throw new ArgumentNullException("The object to generate code for is null."); } // Cast obj to your custom activity for access to its members. Activity1 customActivity = obj as Activity1; if (customActivity == null) { throw new ArgumentException("The obj variable cannot be cast to the Activity type."); } // Retrieve a type provider object. ITypeProvider typeProvider = (ITypeProvider)manager.GetService(typeof(ITypeProvider)); if (typeProvider == null) { throw new InvalidOperationException(); } // TODO: Use types in the System.CodeDOM namespace to generate // code. }若要将自定义代码生成器与自定义活动关联在一起,必须使用 ActivityCodeGeneratorAttribute 修饰活动,如下面的示例所示。[ActivityCodeGenerator(typeof(CustomCodeGenerator))]有关使用 CodeDOM 的更多信息,请参见 Using the CodeDOM。请参见概念 创建自定义活动其他资源 开发工作流活动