2014-03-04 51 views
4

我正在嘗試爲CRUD類創建一些腳手架,並且希望使用T4協助構建這些類。我剛剛開始並且遇到了一個問題,即調用一個生活在同一個項目中的類。例如:從T4模板調用同一個項目中的類

<#@ import namespace="System.Collections.Generic" #> 
<#@ template language="C#" #> 
<#@ output  extension=".cs" #> 
<#@ include file="T4Toolbox.tt" #> 

using System; 
using System.Data; 
using System.Data.Linq; 
using System.Collections.Generic; 

namespace TTFileGenerator 
{ 
<#var entityName = "TEST";#> 
    public class <#=entityName#> 
    { 
    <# 
      MyClass myClass = new MyClass(); 
      List<string> something = myClass.GetSomething() 
      ... 
    #> 
    } 
} 

錯誤:

Compiling transformation: The type or namespace name 'MyClass' could not be found (are you missing a using directive or an assembly reference?)

它是在同一個項目中的公共類。我可以從項目中的其他類訪問它,而不是T4文件。還是一個T4新手。任何方向將不勝感激。

回答

3

你想做的事不會是直截了當的。

爲了讓T4使用一個類(即MyClass),生成器必須引用包含的程序集或完全在T4中定義的類(這是EF代碼生成器所做的)。此外,您可能正在使用設計時T4(讓IDE進行生成)。設計時間t4生成器將保存對dll的引用,因此您將無法再次構建項目。實際上,您必須關閉Visual Studio並重新啓動它。 <嘆息>

如果您決定繼續採用第一種方法 - 我高度贊同 - 您會希望將代碼分解爲兩個程序集(真的是3個)。其中將包含您編寫的代碼,如MyClass。第二個用於生成的代碼。

在這裏創建第三個程序集(命令行項目)並使用runtime t4。這個項目可以引用你的第一個程序集(使用MyClass)並做任何你想做的事情,包括你在這裏展示的代碼!讓代碼生成到第二個程序集中。

在第一個項目的項目設置中,調用第三個項目的命令行工具作爲構建後事件。這也可以是第二個項目的預生成事件。

我用這種方法創建了幾個成功的面向方面編程(AOP)解決方案。唉,這可能不是你希望的答案。

如果你真的很勇敢,可以讓命令行工具重新生成原始項目。這將需要您編譯兩次。我現在不能推薦這個。

+0

感謝。我懷疑這就是爲什麼我看到類似的代碼在其他例子中工作,而它從來沒有真正解釋過。我將嘗試分解應用程序,以便執行該工作的TT可以引用一個程序集,該程序集託管我正在嘗試調用的方法。 – user3219570

+1

VS2012/VS2013應該將程序集加載到不同的應用程序域/影子複製中,以便它不應該鎖定dll。另一種方法是使用roslyn加載語法樹,並且我看過一些使用IDE api的其他文章(以某種方式)。我個人更喜歡在T4文件中定義模型。 – FuleSnabel

+0

@FuleSnabel,這是很好的知道。爲了澄清,我最後一次嘗試使用Design-Time T4生成器引用一個程序集,它在VS2010中;當時,它鎖定了大會。 –

2

想象一下,我會添加一些代碼來幫助其他人,儘管菲利普在頭上打了個針。

我不得不打破我想調用到另一個程序集的類,並使用相對路徑創建程序集引用。我沒有看到任何鎖定(VS 2012)...你只需要記住建立這個組件,如果你做之前將您的T4模板的任何改變:對於非常詳細的回答菲利普

//Reference to another project (for testing, it lives in the debug folder) 
<#@ assembly name="$(SolutionDir)\MyAssembly\bin\x86\Debug\MyAssembly.dll"#> 

<# 
    var helper = new Utilities.MyHelperClass(); 
#> 

<# 
    var something = helper.GetSomething(param1, param2); 
#>