解决T4模板的程序集引用的五种方案

在众多.NET应用下的代码生成方案中,比如CodeDOMBuildProvider, 我觉得T4是最好的一种。关于T4的基本概念和模板结果,可以参考我的文章《基于T4的代码生成方式》。如果要了解T4具体的应用,则可以参考我的文章《创建代码生成器可以很简单:如何通过T4模板生成代码?》(上篇)(下篇)。如果你编写T4模板,你不得不面对一个问题——如何引用一个程序集?VS 2010采用了与VS2008不同的程序集引用的解析机制。本篇文章为你介绍在VS2010下5种不同的程序集引用的方式。

目录
一、添加程序集引用解决不了问题
二、将引用程序集安装到GAC
三、利用VS的PublicAssemblies目录
四、指定程序集的具体路径
五、采用环境变量
六、使用VS宏

一、添加程序集引用解决不了问题

如果你的T4模板需要调用一个自定义的类型,并且该类型定义在某个非系统程序集中,你就需要通过T4<#@ assembly…#>指令引用该程序集。在VS 2008环境下,你只需要为当前项目添加相应的程序集引用,并且通过<@ assembly…#>指令的name属性指定程序集(Dll)的文件名即可。比如,下面的T4模板包含了对程序集Artech.T4AssemblyRefResovle.Foo.dll的引用。

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="Artech.T4AssemblyRefResovle.Foo.dll" #>
<#@ output extension=".cs" #>
public class HelloWorld
{}

但是这种方式对于VS 2010则行不通,因为T4引擎在解析和编译模板的时候并不会从项目引用列表中去定位目标程序集。所以,对于上面的T4模板,会出现如下的编译错误。

二、将引用程序集安装到GAC

其实我们有很多方式来解决这个问题,你首先想到的肯定是将引用的程序集安装到GAC中。没错,这是一种解决方案,如果被引用的程序集具有强签名的话。有一点需要注意的是,T4模板引用某个安装于GAC的程序集的时候,在<#@ assembly…#>指令下不能指定文件扩展名(.dll)。T4模板应该按照如下的方式定义。

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="Artech.T4AssemblyRefResovle.Foo" #>
<#@ output extension=".cs" #>
public class HelloWorld
{}

 

三、利用VS的PublicAssemblies目录

为了让T4引擎能够找到引用的程序集,你可以将其拷贝到VS 2010的PublicAssemblies目的下,该目录为C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies。如果将Artech.T4AssemblyRefResovle.Foo.dll拷贝到该目录下,你在T4模板的<#@ assembly…#>指令下就可以直接指定程序集名称(不包括扩展名)或者程序集文件名(包括扩展名)。

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="Artech.T4AssemblyRefResovle.Foo" #>
<#@ output extension=".cs" #>
public class HelloWorld
{}

指定文件扩展名

<#@ 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.

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="%FooDir%\Artech.T4AssemblyRefResovle.Foo.dll" #>
<#@ output extension=".cs" #>
public class HelloWorld
{}

 

六、使用VS宏

如果被引用的程序集所在目录是在当前解决方案或者当前项目的子目录(这是一种很常见的公共程序集保存方式),你还可以通过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.》

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文链接

时间: 2024-08-03 02:31:21

解决T4模板的程序集引用的五种方案的相关文章

一起谈.NET技术,解决T4模板的程序集引用的五种方案

在众多.NET应用下的代码生成方案中,比如CodeDOM,BuildProvider, 我觉得T4是最好的一种.关于T4的基本概念和模板结果,可以参考我的文章<基于T4的代码生成方式>.如果要了解T4具体的应用,则可以参考我的文章<创建代码生成器可以很简单:如何通过T4模板生成代码?>(上篇)(下篇).如果你编写T4模板,你不得不面对一个问题--如何引用一个程序集?VS 2010采用了与VS2008不同的程序集引用的解析机制.本篇文章为你介绍在VS2010下5种不同的程序集引用的方

Jquery命名冲突解决的五种方案分享_jquery

因为许多 JavaScript 库使用 $ 作为函数或变量名,jquery也一样.其实$只是jquery的一个别名而已,假如我们需要使用 jquery 之外的另一 js 库,我们可以通过调用 $.noConflict() 向该库返回控制权.下面是收集到解决这一问题的五种方案,总有一种你会用得上的. 例一: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w

kettle数据同步的五种方案

数据同步:当数据源发生改变时,其他相关数据也跟着发展变化.根据需求不同可采取以下方案. 1.触发器 在数据库建立增删改的触发器.触发器将变更放到一张临时表里.oracle同步cdc 优点:实时同步 缺点:影响到业务系统,因为需要在业务系统建立触发器 2.日志 通过分析源数据库日志,来获得源数据库中的变化的数据.oracle异步cdc 优点:不影响业务系统 缺点:有一定得延时,对于没有提供日志分析接口的数据源,开发的难度比较大 3.时间戳 在要同步的源表里有时间戳字段,每当数据发生变化,时间戳会记

使用ASP.NET模板生成HTML静态页面的五种方案_实用技巧

ASP.NET模版生成HTML静态页面方案1: 复制代码 代码如下: /// < summary> /// 传入URL返回网页的html代码 /// < /summary> /// < param name="Url">URL< /param> /// < returns>< /returns> public static string getUrltoHtml(string Url) { errorMsg = &

如何生成静态页面的五种方案

静态|页面 方案1:/// <summary>/// 传入URL返回网页的html代码/// </summary>/// <param name="Url">URL</param>/// <returns></returns>public static  string getUrltoHtml(string Url){errorMsg = "";try{System.Net.WebRequest

编写T4模板进行代码生成无法避免的两个话题:&quot;Assembly Locking&quot;&amp;&quot;Debug&quot;

在这之前,我写了一系列关于代码生成和T4相关的文章,而我现在也试图将T4引入我们自己的开发框架.在实践中遇到了一些问题,也解决了不少问题.如果你也在进行T4相关的开发,相信你也一定会遇到这些问题.为此,特意将这些问题和解决方案与朋友们分享,希望在遇到这些问题的时候少走弯路.本篇文章介绍的是两个重要的话题:程序集锁定和调试. 目录 一.程序集引用导致的编译问题 二.T4引擎对引用程序集的锁定 三.Debugger.Break导致VS 2010的Crash 四.在Debugger.Break之前加上

一起谈.NET技术,编写T4模板无法避免的两个话题:&amp;quot;Assembly Locking&amp;quot;&amp;amp;&amp;quot;Debug&amp;quot;

在这之前,我写了一系列关于代码生成和T4相关的文章,而我现在也试图将T4引入我们自己的开发框架.在实践中遇到了一些问题,也解决了不少问题.如果你也在进行T4相关的开发,相信你也一定会遇到这些问题.为此,特意将这些问题和解决方案与朋友们分享,希望在遇到这些问题的时候少走弯路.本篇文章介绍的是两个重要的话题:程序集锁定和调试. 目录 一.程序集引用导致的编译问题 二.T4引擎对引用程序集的锁定 三.Debugger.Break导致VS 2010的Crash 四.在Debugger.Break之前加上

编写T4模板无法避免的两个话题:"Assembly Locking"&"Debug"

在这之前,我写了一系列关于代码生成和T4相关的文章,而我现在也试图将T4引入我们自己的开发框架.在实践中遇到了一些问题,也解决了不少问题.如果你也在进行T4相关的开发,相信你也一定会遇到这些问题.为此,特意将这些问题和解决方案与朋友们分享,希望在遇到这些问题的时候少走弯路.本篇文章介绍的是两个重要的话题:程序集锁定和调试. 目录 一.程序集引用导致的编译问题 二.T4引擎对引用程序集的锁定 三.Debugger.Break导致VS 2010的Crash 四.在Debugger.Break之前加上

Error 2 找不到类型错误提示:或命名空间名称“DBClass”(是否缺少 using 指令或程序集引用?)

问题描述 usingSystem;usingSystem.Data;usingSystem.Data.SqlClient;usingSystem.Configuration;usingSystem.Collections;usingSystem.Web;usingSystem.Web.Security;usingSystem.Web.UI;usingSystem.Web.UI.WebControls;usingSystem.Web.UI.WebControls.WebParts;usingSys