您如何访问T4文本模板中的发布信息?

时间:2018-09-05 16:06:06

标签: c# visual-studio-2017 asp.net-core-mvc t4

您如何访问要在T4文本模板中使用的发布信息?

例如,我想创建一个文本模板,该模板生成一个XML文件,该文件将与ASP.Net Core MVC网站一起发布。根据我在哪里发布网站,生成的文件应该有所不同;生产或测试环境。因此,我在.tt文件中会有类似的内容,以便在生成时,它会根据所选的发布配置文件或发布路径而有所不同:

<#
 if(publishing to A)
{
#>
   text output specific to A
<#
}
else if(publishing to B)
{
#>
   text output specific to B
<#
}
#>

编辑: 我刚刚发现了这一点,它看起来很有希望: using-msbuild-properties-in-t4-templates

1 个答案:

答案 0 :(得分:1)

MSDN blog by Jeremy Kuhne和此blog by Thomas Levesque以及其他MSDN doc之类的其他链接帮助其在VS2017中工作。

我不必在.csproj文件的开头添加任何内容,因为VS2017具有默认情况下已包含的文件。

  

在Visual Studio 2017中,``文本模板转换''组件为   作为Visual Studio扩展的一部分自动安装   开发工作量。您也可以从个人安装   Visual Studio Installer的“组件”选项卡,在“代码”工具下   类别。从个人安装Modeling SDK组件   组件标签。

我最终在文件末尾进行了以下.csproj更改。这将允许在T4模板中使用所选的构建配置,并在每个构建上重新生成所有模板:

  <PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
    <!-- Run the Transform task at the start of every build -->
    <TransformOnBuild>true</TransformOnBuild>
    <!-- -->
    <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
    <!-- Transform every template every time -->
    <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
  </PropertyGroup>

  <!-- add AFTER import for $(MSBuildToolsPath)\Microsoft.CSharp.targets -->
  <Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" />

    <ItemGroup>
    <T4ParameterValues Include="BuildConfiguration">
        <Value>$(Configuration)</Value>
        <Visible>False</Visible>
    </T4ParameterValues>
  </ItemGroup>

    <Target Name="CreateT4ItemListsForMSBuildCustomTool" BeforeTargets="CreateT4ItemLists" AfterTargets="SelectItemsForTransform">
    <ItemGroup>
        <T4Transform Include="@(CreateT4ItemListsInputs)" Condition="'%(CreateT4ItemListsInputs.Generator)' == 'MSBuild:TransformAll'" />
    </ItemGroup>
  </Target>

这是csproj文件顶部的内容,但可以通过VS2017进行配置。关键点是名为Development的自定义构建配置和DEVELOPMENT的定义常量:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <Configurations>Debug;Release;Development</Configurations>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Development|AnyCPU'">
    <DebugType>none</DebugType>
    <DefineConstants>TRACE;DEVELOPMENT</DefineConstants>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DebugType>full</DebugType>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <DebugType>none</DebugType>
    <DefineConstants>TRACE;RELEASE</DefineConstants>
  </PropertyGroup>

这在T4模板中显示了如何访问新的BuildConfiguration参数:

<#@ template hostspecific="true" language="C#" #>
<#@ output extension=".txt" #>
<#@ assembly name="EnvDTE" #>
<#  
    //Build time.
    string configName = Host.ResolveParameterValue("-", "-", "BuildConfiguration");
    if (string.IsNullOrWhiteSpace(configName))
    {
        try
        {
            //Design time.
            var serviceProvider = (IServiceProvider)Host;
            EnvDTE.DTE dte = (EnvDTE.DTE)serviceProvider.GetService(typeof(EnvDTE.DTE));
            configName = dte.Solution.SolutionBuild.ActiveConfiguration.Name;
        }
        catch(Exception ex)
        {
            configName = ex.Message;
        }
    }
#>
<#=configName#>

.tt文件上的以下属性设置:

Build Action: None
Copy to Output Directory: Do Not Copy
Custom Tool: MSBuild:TransformAll

和一个名为“ Development”的自定义构建配置。 T4模板中的代码将选择“调试”,“发布”和“开发”。开发构建配置是发行配置的副本。该项目的条件编译符号为“ DEVELOPMENT”,因此以下代码在Program.cs中起作用,以将环境强制为“开发”模式。可以在项目属性>构建>常规下设置符号。通过“开发”构建配置将发布配置文件设置为发布到测试服务器URL。

    public static void Main(string[] args)
    {
        //https://andrewlock.net/how-to-set-the-hosting-environment-in-asp-net-core/
            string mode = "";

#if DEVELOPMENT
            mode  = "DEVELOPMENT";
#elif DEBUG
            mode = "DEBUG";
#elif RELEASE
             mode = "RELEASE";
#endif

            switch (mode.ToUpper())
            {
                case "DEVELOPMENT":
                //Programmatically force the application to use the Development environment.
                    CreateWebHostBuilder(args).UseEnvironment("Development").Build().Run();
                    break;
                default:
                    CreateWebHostBuilder(args).Build().Run();
                    break;
            }
    }