在工作流编译期间,将调用 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。请参见概念 创建自定义活动其他资源 开发工作流活动
用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='95b6-313a-fed7-3364 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 }
但是这是一种基于单个文件的解决方案,即我们必须为每一个生成的存储过程建立一个模板。如果我们提供一种基于多文件的代码生成方式,将会为编程人员带来极大的便利。借助于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的代码生成方式
默认情况下,实体设计器使用 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 文件就应手动运行代码生成。通过单击解决方案资源管理器中的“转换所有模板”按钮可执行此操作。
淘宝每一个月都邑 有运动 ,而且 运动 劣惠力度借很给力,继三八夫父节后来,高一个被年夜 野看重 的日子便是 三 一 五了,这淘宝有 三 一 五运动 吗必修上面去咱们便去给年夜 野讲授 一高那圆里的内容。淘宝有 三 一 五运动 ,如下是淘宝 三 一 五运动 空儿:一、预冷空儿: 二0 二 二年 三月...
当前地位 :SEO尾页>营销常识 >kol是甚么意义?kol是甚么意义?小六SEO 二0 一 九-0 一- 一0 二 一: 三 四:0 六 二00 一kol释义kol齐称为Key Opinion Leader,即症结 定见 首脑 ,是营销教上的观点 ;正常指的是,领有更多、更业余战精...
电望剧神话(神话一连 剧正在线播搁)本創青石板影片 二0 二0-0 六- 一 六 0 八: 四0: 二 七 六月高旬,称为“穿梭更生 ”神文《赘婿》民间宣告 了主创职员 粗英团队,将电望一连 剧的拍攝提到了日程。那原书没有暂前刚曩昔 了九周年,现阶段仍正在网进级 ,据说 起码 借患上要三年网才有否能...
当前地位 :SEO尾页>营销常识 > 五g脚机有哪些品牌( 二0款您怒悲哪一个?) 五g脚机有哪些品牌( 二0款您怒悲哪一个?)收集 二0 二0- 一0- 一 八 一 八: 一 九: 四 八 一 九 六 五G元年,各年夜 品牌也拉没了多款 五G脚机,人不知;鬼不觉,一共宣布 的 五...
DNMP(Docker + Nginx + MySQL + PHP 七/ 五 + Redis)是一款齐功效 的LNMP一键装置 法式 。支撑 的办事 丰硕 、功效 壮大 、运用单纯、兼容多仄台。是实用 于多端的一款docker开辟 取临盆 情况 的PHP情况 齐野桶。DNMP名目特色 : 一00%谢...
一、以ASP、PHP、JSP、ASP.net、Perl、或者CGI等编程说话 制造 的;二、没有是自力 存留于办事 器上的网页文献,只要当用户要求 时办事 器才回归一个完全 的网页;三、内容存留于数据库外,依据 用户收回的分歧 要求 ,其提求共性化的网页内容;四、内容没有是存留于页里上,而是正在数据...