2012-05-25 78 views
1

我正在創建一個T4模板,我希望根據某些條件有條件地包含模板。例如,我曾嘗試以下...T4有條件地包含模板

<#switch(iocContainer) {#> 
<#case "Autofac":#> 
    <#@ include file="Autofac\EntityTemplate.ttinclude" #> 
    <#@ include file="Autofac\ServiceTemplate.ttinclude" #> 
    <#@ include file="Autofac\RepositoryTemplate.ttinclude" #> 
    <#@ include file="Autofac\DbContextTemplate.ttinclude" #> 
<#break;#> 

<#case "Castle":#> 
    <#@ include file="Castle\EntityTemplate.ttinclude" #> 
    <#@ include file="Castle\ServiceTemplate.ttinclude" #> 
    <#@ include file="Castle\RepositoryTemplate.ttinclude" #> 
    <#@ include file="Castle\DbContextTemplate.ttinclude" #> 
<#break;#> 

<#case "nInject":#> 
    <#@ include file="nInject\EntityTemplate.ttinclude" #> 
    <#@ include file="nInject\ServiceTemplate.ttinclude" #> 
    <#@ include file="nInject\RepositoryTemplate.ttinclude" #> 
    <#@ include file="nInject\DbContextTemplate.ttinclude" #> 
<#break; 
}#> 

的問題是模板引擎運行時,它似乎預處理評估任何代碼之前所有的包括。所以上面的switch語句沒有運行,T4試圖包含所有的文件。

有沒有辦法有條件地包含T4模板?

回答

1

不,T4不包括有條件的設計。指令將全部被處理。

如果你反轉你的邏輯,你可以解決這個問題。將T4內容上下切分爲兩個單獨的文件(我們稱它們爲start.ttincludeend.ttinclude)。然後創建三個單獨的T4模板,稱爲autofac.tt,castle.ttninject.tt。這些每一個都將看起來是這樣的(這是castle.tt):

<#@ include file="start.ttinclude" #> 
<#@ include file="Castle\EntityTemplate.ttinclude" #> 
<#@ include file="Castle\EntityTemplate.ttinclude" #> 
<#@ include file="Castle\EntityTemplate.ttinclude" #> 
<#@ include file="Castle\EntityTemplate.ttinclude" #> 
<#@ include file="end.ttinclude" #> 
+0

好的建議。我認爲這會起作用。 –

1

或者,將一個#IF #ENDIF塊內模板的內容和使用#define語句來使內容被跳過,即使文件本身就包括在內。

0

如果您不介意在Visual Studio容器中運行,那麼DTE可以在這裏幫助您。

<#@ template hostspecific="true" language="C#" #> 
<#@ output extension=".cs" #> 
<#@ assembly name="EnvDTE" #> 
<#@ Assembly Name="System.Core" #> 
<#@ Assembly Name="System.Data" #> 
<#@ Assembly Name="System.Xml" #> 
<#@ Assembly Name="System.Xml.Linq" #> 
<#@ import namespace="EnvDTE" #> 
<#@ import namespace="System" #> 
<#@ Import namespace="System.Linq"     #> 
<#@ Import namespace="System.Reflection"    #> 
<#@ Import namespace="System.Linq.Expressions"  #> 
<#@ Import namespace="System.Collections.Generic"  #> 
<#@ Import namespace="System.Linq"     #> 
<#@ Import namespace="System.Text"     #> 
<# 
    if(isDefined("spike2" , "TTs")) { 
     WriteLine("//the constant TTs is defined"); 
    } 
    else 
    { 
     WriteLine("//the constant TTs is not defined"); 
    } 
#> 
<#+ 
     private bool isDefined(string projectName, string constantToCheck){ 
      IServiceProvider serviceProvider = (IServiceProvider)this.Host; 
      DTE dte = serviceProvider.GetService(typeof(DTE)) as DTE; 

      try 
      { 
       // find a project called "Spike2" 
       Project prj = (from p in getProjects(dte) where p.Name.ToLower() == projectName.ToLower() select p).FirstOrDefault(); 

       // get its active configuration 
       var config = prj.ConfigurationManager.ActiveConfiguration; 


       var defineConstants = (from p in getConfigProperties(config) where p.Name == "DefineConstants" select p.Value).FirstOrDefault().ToString(); 
       var constants = defineConstants.Split(';'); 
       return Array.Exists(constants, define => define == constantToCheck); 
      } 
      catch(Exception ex) 
      { 
       Write(ex.Message); 
      } 
      return false; 
     } 

     static private IEnumerable<Property> getConfigProperties(Configuration config) { 
      for(int i=1; i <= config.Properties.Count; i++) 
      { 
       yield return config.Properties.Item(i); 
      } 
     } 

     static private IEnumerable<Project> getProjects(DTE dte) { 
      for(int i=1; i <= dte.Solution.Projects.Count; i++) 
      { 
       yield return dte.Solution.Projects.Item(i); 
      } 
     } 
#> 
0

我想爲每個開發人員機器添加一個不同的配置文件,並且還要有一個默認的app.config。這隻有在您不想處理「包含」文件時纔有效。

文件名App.tt.

<#@ template debug="false" hostspecific="true" language="C#" #> 
<#@ import namespace="System" #> 
<#@ import namespace="System.IO" #> 
<#@ output extension=".config" #> 
<# 
string pathToConfigurations = Host.ResolvePath("Configurations"); 
string pathToMachine = Path.Combine(pathToConfigurations, Environment.MachineName + ".config"); 
if (File.Exists(pathToMachine)) 
{ 
    Write(File.ReadAllText(pathToMachine)); 
} 
else 
{ 
    Write(File.ReadAllText(Path.Combine(pathToConfigurations, "App.config"))); 
} 
#>