解決T4模板的程序集引用的五種方案

在衆多.NET應用下的代碼生成方案中,好比CodeDOMBuildProvider, 我以爲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

image

2、將引用程序集安裝到GAC

其實咱們有不少方式來解決這個問題,你首先想到的確定是將引用的程序集安裝到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
{}

 

 

3、利用VS的PublicAssemblies目錄

爲了讓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
{}

 

4、指定程序集的具體路徑

若是被引用的程序集被沒有被簽名,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
{}

 

 

5、採用環境變量

採用程序集文件的絕對路徑這種硬編碼並非一種推薦的解決方案,由於在團隊開發中,每一個開發人員用於存放同一個程序集的地址可能不一樣,在這種狀況下你能夠採用環境變量的方式。你能夠定義個環境變量(好比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
{}

 

6、使用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.》

 

程序員的基礎教程:菜鳥程序員

相關文章
相關標籤/搜索