我正在尝试解决 T4 集成到 .NET 4.8 以后的任何版本中的噩梦。
高级目标是,在单个解决方案中(可能在单个项目或其他方式中),在 .NET 9.0 中编译实用程序 DLL,在一些 T4 文件中引用它,然后运行 T4 生成。
如果实用程序 DLL 基本上只引用
System
,则生成工作正常。但是,它需要访问多个符号,其中任何一个都会破坏构建:
AttributeUsage
System.Reflection.FieldInfo
System.Diagnostics.StartInfo
等等。引入这些符号会产生此处描述的行为:
T4 模板无法加载文件或程序集“System.Runtime,版本 = 4.2.0.0”
其中
System.Runtime
无法加载。
我不会像
这个答案那样修改
\Users\
中的程序集绑定,因为此解决方案需要可移植到其他库存环境。
这个答案中描述的扩展RdjNL似乎不可能,因为它不支持模板参数,并且我需要能够传入模板参数以使用
T4ParameterValues
加载实用程序程序集。
这让我尝试迁移到新的 TextTransformCore,这已经更糟糕了,因为它没有 IDE 内生成支持,并且也拒绝作为手动构建后步骤工作。
这个 .csproj 应该是可重现的:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Platforms>x64</Platforms>
<TargetFramework>net9.0-windows</TargetFramework>
<OutputType>Library</OutputType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PropertyGroup>
<PropertyGroup>
<!-- Legacy T4-related properties -->
<!-- Force the use of the new T4 generator. The legacy one doesn't work with newer .NET. -->
<TextTransformPath>$(DevEnvDir)TextTransformCore.exe</TextTransformPath>
<!--
Custom parameter to pass into T4 so it can load the DLL.
This is a nightmare because most project properties aren't available from an msbuild context.
-->
<ProtocolAssembly>$(SolutionDir)Protocol\bin\$(Platform)\$(Configuration)\$(TargetFramework)\Protocol.dll</ProtocolAssembly>
</PropertyGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<!--
As shown, this throws
MyTemplate.tt(0,0) : error : Running transformation: System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
If -P is added:
-P "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\9.0.0\ref\net9.0"
then the entire runtime implodes with dozens of errors like
1>Error : error : There was a problem loading the assembly 'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\9.0.0\ref\net9.0\System.ComponentModel.TypeConverter.dll' The following Exception was thrown:
1>System.IO.FileLoadException: Could not load file or assembly 'System.ComponentModel.TypeConverter, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL'.
1> at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
1> at Microsoft.VisualStudio.TextTemplating.Core.SessionLoadContext.LoadFromAssemblyPath(String assemblyPath)
1> at Microsoft.VisualStudio.TextTemplating.Core.TransformationRunner.LoadExplicitAssemblyReferences(IEnumerable`1 references)
1>EXEC : warning : MyTemplate.tt(1,1) : warning CS8021: Compiling transformation: CS8021: No value for RuntimeMetadataVersion found. No assembly containing System.Object was found nor was a value for RuntimeMetadataVersion specified through options.
1>EXEC : error : MyTemplate.tt(1,1) : error CS0518: Compiling transformation: CS0518: Predefined type 'System.Void' is not defined or imported
1>EXEC : error : MyTemplate.tt(1,1) : error CS0518: Compiling transformation: CS0518: Predefined type 'System.Void' is not defined or imported
1>EXEC : error : MyTemplate.tt(1,1) : error CS0518: Compiling transformation: CS0518: Predefined type 'System.Boolean' is not defined or imported
1>EXEC : warning : MyTemplate.tt(1,1) : warning CS1701: Compiling transformation: CS1701: Assuming assembly reference 'System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'Microsoft.VisualStudio.TextTemplating.Core' matches identity 'System.Runtime, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy
-->
<Exec Command=""$(TextTransformPath)" -r "$(ProtocolAssembly)" $(ProjectDir)MyTemplate.tt" />
</Target>
</Project>
使用此模板:
<#@ template language="C#" debug="true" linePragmas="true" hostspecific="false" visibility="internal" #>
<#@ output extension=".py" encoding="utf-8" #>
以及任何引用我上面描述的符号的存根 DLL。
我将写一个自我回答,描述降级到 .NET 8.0 可以解决该问题,因为
Microsoft.VisualStudio.TextTemplating.Core
也引用了这一点。
赠品是这一行:
警告CS1701:编译转换:CS1701:假设
使用的程序集引用'System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
与'Microsoft.VisualStudio.TextTemplating.Core'
的身份'System.Runtime, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
匹配,您可能需要提供运行时策略'System.Runtime'
在我找到更巧妙的方法将 .NET 8 映射到 .NET 9 之前,最简单的解决方法是更改 DLL,使其面向 .NET 8。此解决方法是成功的。对应的.csproj需要有
<TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>