解決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模板,會出現如下的編譯錯誤。

image  二、將引用程序集安裝到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.》


作者: Artech 來源: 博客園 2014-07-25 18:36:09

[新一篇] 看似簡單!解讀C#程序員最易犯的7大錯誤

[舊一篇] 實驗表明人類穿越時空并非不可能
回頂部
寫評論


評論集


暫無評論。

稱謂:

内容:

驗證:


返回列表