0

我正在创建一个 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 模板?

4

4 回答 4

1

不,T4 不包含设计的条件包含。这些指令都将被处理。

如果你颠倒你的逻辑,你可以解决这个问题。将 switch 语句上方和下方的 T4 内容拆分为两个单独的文件(我们称它们为start.ttincludeand end.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" #>
于 2012-05-25T14:57:57.010 回答
1

或者,将模板的内容放在#IF #ENDIF 块中,并使用#DEFINEs 使内容被跳过,即使包含文件本身也是如此。

于 2012-06-04T18:36:56.417 回答
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);
            }
        }
#>
于 2014-08-21T06:21:43.400 回答
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")));  
}
#>
于 2016-04-08T20:33:31.510 回答