我最近将测试项目迁移到.NET Core 2.0。该测试项目使用文本模板生成一些重复的代码。之前的项目有一个构建目标,可以在构建之前生成所有T4模板。因此,生成的代码也不会签入VCS。
我在项目中使用了这个片段来确保构建模板:
<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
包,但这有两个问题:
答案 0 :(得分:1)
你有人为dotnet核心编写端口。
这是旧的:http://www.bricelam.net/2015/03/12/t4-on-aspnet5.html
或者完全使用不同的模板工具,但我当然明白这是不是一种选择。
答案 1 :(得分:0)
要支持在构建dotnet build
时构建T4模板,您需要使用Custom Text Template Host
,它已用于.NET Core(https://github.com/atifaziz/t5)。要包含它,请在任何ItemGroup
该元素中添加到您的项目中:
<DotNetCliToolReference Include="T5.TextTransform.Tool" Version="1.1.0-*" />
。
由于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'"
。
您还应该在导入<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="'$(MSBuildRuntimeType)'=='Full'" />
之前添加Microsoft.TextTemplating.targets
,以使所有内容都能在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
答案 2 :(得分:0)
或仅使用T4Executer。您可以设置要在构建之前,构建之后执行的模板,或者忽略特定模板。与VS2017-19配合使用