.net T4有条件地包括模板

5fjcxozz  于 2023-06-07  发布在  .NET
关注(0)|答案(4)|浏览(225)

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

ttygqcqt

ttygqcqt1#

否,T4在设计上不包含条件包含。所有指令都将被处理。
如果你颠倒一下你的逻辑,你就能解决这个问题。将switch语句上方和下方的T4内容拆分为两个单独的文件(我们称之为start.ttincludeend.ttinclude)。然后创建三个单独的T4模板,分别称为autofac.ttcastle.ttninject.tt。它们看起来都像这样(这是castle.tt):

<#@ include file="start.ttinclude" #>
<#@ include file="Castle\EntityTemplate.ttinclude" #>
<#@ include file="Castle\ServiceTemplate.ttinclude" #>
<#@ include file="Castle\RepositoryTemplate.ttinclude" #>
<#@ include file="Castle\DbContextTemplate.ttinclude" #>
<#@ include file="end.ttinclude" #>
ymzxtsji

ymzxtsji2#

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

neekobn8

neekobn83#

如果您不介意在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);
            }
        }
#>
wnavrhmk

wnavrhmk4#

我想为每台开发人员机器包含一个不同的配置文件,并有一个默认的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")));  
}
#>

相关问题