代码改变世界

T4+VSIX 打造Visual Studio 2010 中的Entity代码生成自定义工具(下)

2011-03-17 23:21  落小呆  阅读(2841)  评论(3编辑  收藏  举报

上一篇文章中主要介绍了如何开发根据“文本模板”生成代码的自定义工具,后面有人反应说写得比较混乱,看完了也不知道说啥,自己也回头去看了下,文章的讲述的思路确是存在比较大的问题,所以进行了修改,如果还有什么疑问或者意见希望能够提出来,那么接下来继续如果在前面开发的自定义工具的基础上进行修改,变成ADO.NET Entity的实体生成自定义工具。

在这之前首先简单介绍下Entity实体代码生成的过程,打开测试项目,添加新项“ADO.NET 实体数据模型,如下图所示:

image

点击【添加】按钮后,会提示“选择模型内容”,一种是“从数据库生成”,另外一种是“空模型”,考虑到只是测试实体生成而已,直接选择空模型,点击【完成】按钮,在项目中会添加“Model.edmx”文件以及生成的子文件“Model.Designer.cs”,查看“Model.edmx”文件的属性,可以看到该文件的“自定义工具”的属性值为“EntityModelCodeGenerator”,这也就是Entity实体默认生成的自定义工具。,如下图所示:

image

那么接下来我们要做的事就是让我们开发的自定义工具也能和“EntityModelCodeGenerator”一样生成Entity的实体文件“Model.Designer.cs”。只需将Entity实体生成的“文本模板”作为固定的生成模板提供给前面开发的“MyCodeGenerator”自定义工具的代码生成的“文本模板”输入基本上就算完成,但在操作过程中还是有些细节地方需要注意。

那么接下来我们在前面开发的“MyCodeGenerator”自定义工具的基础上进行修改,打开前面开发过的项目,在CodeGenerator目录中中添加新项,选择“ADO.NET EntityObject生成器”,也就是生成Entity实体的“文本模板”,如下图所示,然后点击【添加】。

image

添加文件后首先修改文件“自定义工具”属性为空,然后接下来就是就是对该文本模板的修改,首先我们在文本模板中会发现有一句“<#@ include file="EF.Utility.CS.ttinclude"#>”,这句代码的含义简单理解就是在生成代码的时候要引用“EF.Utility.CS.ttinclude”文件在该模板里面,平常我们如果是用文本模板自带的自定义工具“TextTemplatingFileGenerator”进行生成的时候是可以正常引用到该文件(注册表里面会有路径的相关信息),可惜在我们自己开发的自定义工具里面显然就不行了,那么接下来主要的修改就是将“EF.Utility.CS.ttinclude”加入到我们的模板中。

首先当然我们要找到该文件,该文件可以在“VS安装文件夹\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes”中可以找到,最简单的方法就是将文件中的文本直接拷贝到前面添加的模板项目中,但注意由于文本模板的语法限制,插入的位置是有要求的,如图所示:

image

插入文本之后注意要删除掉文本中的“<#@ include file="EF.Utility.CS.ttinclude"#>”。

在模板中可以看到“$edmxInputFile$”这样的文本,这部分文本是需要在生成之前用实际的.edmx文件的路径进行替换的路径标识符,如图所示:

image

但由于我们在模板中加入了“EF.Utility.CS.ttinclude”的文本,而且该文本中有代码逻辑也涉及到“$edmxInputFile$”的判断,不能被替换掉(会导致生成错误),那么我们需要将前面的路径标识符进行修改,暂且修改为$entity.edmx$,如下图所示:

image

到此为止生成模板的工作就算完成了,接下来将修改后的文本模板文件“添加到资源”,注意添加后修改该资源文件属性“FileType”为“Text”,如图所示:

image

接下来我们修改“MyCodeGenerator”类的代码生成逻辑,比较简单,具体代码如下:

 

    [System.Runtime.InteropServices.Guid("391B243E-DB88-42F8-8F64-A355042D7507")]
    
public class MyCodeGenerator : TemplatedCodeGenerator
    {
        
protected override byte[] GenerateCode(string inputFileName, string inputFileContent)
        {
            
string template = Resources.Model1.Replace("$entity.edmx$", inputFileName);

            
return base.GenerateCode(inputFileName, template);
        }
    }

 

我们Entity实体代码生成自定义工具就可以算开发完成,注意安装重新编译的“Kevin.Develop.CodeGenerateCustomTool.vsix”扩展时,需要在Visual Studio 的【工具】【扩展管理器】中找到已经安装的“Kevin.Develop.CodeGenerateCustomTool”,并卸载。

安装成功后,重新打开我们的测试项目,修改“Model.edmx”文件的自定义工具属性为“MyCodeGenerator”,右键点击该文件【运行自定义工具】,会发现同样也能生成Entity的实体相关代码,说明我们的自定义工具正常运行,如图所示:

image

最后简单总结下:

  • 在Entity文本模板修改的时候,可以考虑分割文件,然后在代码中在进行拼接,这样的好处就是能够更方面重用文本模板中定义的辅助方法,在示例代码中会有简单的例子。
  • 通过修改Entity实体生成的模板,可以根据自己需要更加灵活的去生成项目中实体类。
  • 了解Visual Studio中文件以及代码的添加等操作可以让自定义工具变得更加强大。

看完这两篇文章后,通过代码生成可以让我们能去做更少的体力活,所有如果有什么好的生成一些相关代码的建议可以提出来交流讨论。

 

示例代码