在众多.NET应用下的代码生成方案中,好比CodeDOM,BuildProvider, 我以为T4是最好的一种。关于T4的基本概念和模板结果,能够参考个人文章《基于T4的代码生成方式》。若是要了解T4具体的应用,则能够参考个人文章《建立代码生成器能够很简单:如何经过T4模板生成代码?》(上篇)(下篇)。若是你编写T4模板,你不得不面对一个问题——如何引用一个程序集?VS 2010采用了与VS2008不一样的程序集引用的解析机制。本篇文章为你介绍在VS2010下5种不一样的程序集引用的方式。html
目录
1、添加程序集引用解决不了问题
2、将引用程序集安装到GAC
3、利用VS的PublicAssemblies目录
4、指定程序集的具体路径
5、采用环境变量
6、使用VS宏程序员
1、添加程序集引用解决不了问题web
若是你的T4模板须要调用一个自定义的类型,而且该类型定义在某个非系统程序集中,你就须要经过T4<#@ assembly…#>指令引用该程序集。在VS 2008环境下,你只须要为当前项目添加相应的程序集引用,而且经过<@ assembly…#>指令的name属性指定程序集(Dll)的文件名便可。好比,下面的T4模板包含了对程序集Artech.T4AssemblyRefResovle.Foo.dll的引用。app
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="Artech.T4AssemblyRefResovle.Foo.dll" #>
<#@ output extension=".cs" #>
public class HelloWorld
{}
可是这种方式对于VS 2010则行不通,由于T4引擎在解析和编译模板的时候并不会从项目引用列表中去定位目标程序集。因此,对于上面的T4模板,会出现以下的编译错误。asp.net
其实咱们有不少方式来解决这个问题,你首先想到的确定是将引用的程序集安装到GAC中。没错,这是一种解决方案,若是被引用的程序集具备强签名的话。有一点须要注意的是,T4模板引用某个安装于GAC的程序集的时候,在<#@ assembly…#>指令下不能指定文件扩展名(.dll)。T4模板应该按照以下的方式定义。ide
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="Artech.T4AssemblyRefResovle.Foo" #>
<#@ output extension=".cs" #>
public class HelloWorld
{}
为了让T4引擎可以找到引用的程序集,你能够将其拷贝到VS 2010的PublicAssemblies目的下,该目录为C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies。若是将Artech.T4AssemblyRefResovle.Foo.dll拷贝到该目录下,你在T4模板的<#@ assembly…#>指令下就能够直接指定程序集名称(不包括扩展名)或者程序集文件名(包括扩展名)。visual-studio
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="Artech.T4AssemblyRefResovle.Foo" #>
<#@ output extension=".cs" #>
public class HelloWorld
{}
指定文件扩展名ui
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="Artech.T4AssemblyRefResovle.Foo.dll" #>
<#@ output extension=".cs" #>
public class HelloWorld
{}
若是被引用的程序集被没有被签名,GAC的方式则不能使用,在这种状况下你须要指定程序集文件所在的位置,最直接的固然就是指定程序集文件的绝对路径。在下面的T4模板中,<#@ assembly…#>指令中指定的就是Artech.T4AssemblyRefResovle.Foo.dll文件的绝对路径。编码
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="D:\T4AssemblyRefResovle\Lib\Artech.T4AssemblyRefResovle.Foo.dll" #>
<#@ output extension=".cs" #>
public class HelloWorld
{}
采用程序集文件的绝对路径这种硬编码并非一种推荐的解决方案,由于在团队开发中,每一个开发人员用于存放同一个程序集的地址可能不一样,在这种状况下你能够采用环境变量的方式。你能够定义个环境变量(好比FooDir)表示本机用于保存程序集的目录(好比D:\T4AssemblyRefResovle\Lib),那么被引用的程序集就能够表示成:%FooDir%\Artech.T4AssemblyRefResovle.Foo.dll.spa
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="%FooDir%\Artech.T4AssemblyRefResovle.Foo.dll" #>
<#@ output extension=".cs" #>
public class HelloWorld
{}
若是被引用的程序集所在目录是在当前解决方案或者当前项目的子目录(这是一种很常见的公共程序集保存方式),你还能够经过VS的宏命令来指定该目录。好比咱们的Artech.T4AssemblyRefResovle.Foo.dll保存在当前解决方案目录的Lib子目录下,该程序集的路径就能够表示成:$(SolutionDir)\Lib\Artech.T4AssemblyRefResovle.Foo.dll。
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="$(SolutionDir)\Lib\Artech.T4AssemblyRefResovle.Foo.dll" #>
<#@ output extension=".cs" #>
public class HelloWorld
{}
注:上面提到的程序集引用解决方案来源于《T4 Template error - Assembly Directive cannot locate referenced assembly in Visual Studio 2010 project.》
程序员的基础教程:菜鸟程序员