【问题标题】:TextTemplating target in a .Net Core project.Net Core 项目中的 TextTemplating 目标
【发布时间】:2018-05-21 08:07:13
【问题描述】:

我最近将一个测试项目迁移到 .NET Core 2.0。该测试项目使用文本模板生成一些重复代码。之前的项目有一个构建目标,用于在构建之前生成所有 T4 模板。因此,生成的代码也不会签入到 VCS。

我曾在项目中使用过这个 sn-p 来确保构建模板:

<PropertyGroup>
  <!-- Default VisualStudioVersion to 15 (VS2017) -->
  <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
  <!-- Determinate VSToolsPath -->
  <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
  <!-- Run T4 generation if there are outdated files -->
  <TransformOnBuild>True</TransformOnBuild>
  <TransformOutOfDateOnly>True</TransformOutOfDateOnly>
</PropertyGroup>
<!-- Import TextTemplating target -->
<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" />

我的第一个方法是保留此片段并将其复制到新的 .NET Core 项目文件中。

在 Visual Studio 中,这是可行的,因为显然 VSToolsPath 设置正确。但是,当我运行 .NET Core SDK 工具时,例如 dotnet test(就像我在构建服务器上所做的那样),VSToolsPath 映射到 Program Files\dotnet\sdk\2.0.3 并且在那里,找不到文本模板目标。

因为这不起作用,我也尝试简单地从 Nuget 安装 Microsoft.VisualStudio.TextTemplating 包,但这有两个问题:

  1. 它不正式支持 .NET Core 并为 .NET 4.6.1 和
  2. 安装
  3. Nuget 似乎没有安装任何东西,所以我无法调整项目文件中的路径。

【问题讨论】:

  • 您找到解决方案了吗?

标签: visual-studio-2017 .net-core t4


【解决方案1】:

要在构建 dotnet build 时支持构建 T4 模板,您需要使用 .NET Core (https://github.com/atifaziz/t5) 已经存在的 Custom Text Template Host。要包含它,请在您的项目中添加任何 ItemGroup 这个元素: &lt;DotNetCliToolReference Include="T5.TextTransform.Tool" Version="1.1.0-*" /&gt;。 由于 Visual Studio 已经拥有自己的 Text Template Host 实现,因此您添加的元素应仅适用于 .NET Core。例如:

<ItemGroup Condition="'$(MSBuildRuntimeType)'=='Core'">
    <DotNetCliToolReference Include="T5.TextTransform.Tool" Version="1.1.0-*" />
</ItemGroup>

同时,您应该在 .NET Core 之外调整您对 Visual Studio 的文本模板主机的设置,如下所示:Condition="'$(MSBuildRuntimeType)'=='Full'"

您还应该在导入 Microsoft.TextTemplating.targets 之前添加 &lt;Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="'$(MSBuildRuntimeType)'=='Full'" /&gt; 以使一切在 Visual Studio 中使用 .NET Core csproj 正常工作。

如果您需要能够清理所有生成的代码,您应该将您的模板从*.tt 重命名为*.Generated.tt,所有代码将在*.Generated.cs 下生成,并且可以过滤掉这些文件在dotnet clean 行动。

csproj 中的完整示例:

<!-- T4 build support for .NET Core (Begin) -->

<ItemGroup Condition="'$(MSBuildRuntimeType)'=='Core'">
  <DotNetCliToolReference Include="T5.TextTransform.Tool" Version="1.1.0-*" />
  <TextTemplate Include="**\*.Generated.tt" />
  <Generated Include="**\*.Generated.cs" />
</ItemGroup>

<Target Name="TextTemplateTransform" BeforeTargets="BeforeBuild" Condition="'$(MSBuildRuntimeType)'=='Core'">
  <ItemGroup>
    <Compile Remove="**\*.cs" />
  </ItemGroup>
  <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tt %(TextTemplate.Identity)" />
  <ItemGroup>
    <Compile Include="**\*.cs" />
  </ItemGroup>
</Target>

<Target Name="TextTemplateClean" AfterTargets="Clean">
  <Delete Files="@(Generated)" />
</Target>

<!-- T4 build support for .NET Core (End) -->


<!-- T4 build support for Visual Studio (Begin) -->

<PropertyGroup Condition="'$(MSBuildRuntimeType)'=='Full'">
  <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
  <!-- This is what will cause the templates to be transformed when the project is built (default is false) -->
  <TransformOnBuild>true</TransformOnBuild>
  <!-- Set to true to force overwriting of read-only output files, e.g. if they're not checked out (default is false) -->
  <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
  <!-- Set to false to transform files even if the output appears to be up-to-date (default is true)  -->
  <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>

<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="'$(MSBuildRuntimeType)'=='Full'" />
<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" Condition="'$(MSBuildRuntimeType)'=='Full'" />

<!-- T4 build support for Visual Studio (End) -->

如果您不想重命名模板文件并且不需要清理它们,请替换:

  <TextTemplate Include="**\*.Generated.tt" />
  <Generated Include="**\*.Generated.cs" />

与:

  <TextTemplate Include="**\*.tt" />

然后删除:

<Target Name="TextTemplateClean" AfterTargets="Clean">
  <Delete Files="@(Generated)" />
</Target>

欲了解更多信息,请参阅:

如何在dotnet build 上设置代码生成: https://notquitepure.info/2018/12/12/T4-Templates-at-Build-Time-With-Dotnet-Core/

如何在构建时为 Visual Studio 和 .NET Core csproj 设置代码生成: https://thomaslevesque.com/2017/11/13/transform-t4-templates-as-part-of-the-build-and-pass-variables-from-the-project/

从单个 T4 模板生成多个文件的完整示例: https://github.com/Konard/T4GenericsExample

更新:

GitHub.com/Mono/T4is even better.

【讨论】:

    【解决方案2】:

    你受制于为 dotnet core 编写端口的人。

    这是旧的:http://www.bricelam.net/2015/03/12/t4-on-aspnet5.html

    或者完全使用不同的模板工具,当然我理解这不是一个选项。

    【讨论】:

      【解决方案3】:

      或者只使用T4Executer。您可以设置在构建之前、构建之后执行哪些模板或忽略特定模板。适用于 VS2017-19

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-29
        • 2016-11-26
        • 2021-11-05
        • 2018-05-01
        • 2018-12-08
        • 1970-01-01
        • 2016-11-12
        • 2017-08-16
        相关资源
        最近更新 更多