如何避免在T4模板上找不到DLL错误?

How to avoid DLL not found error on T4 template?

提问人:just_a_developer 提问时间:11/15/2023 更新时间:11/15/2023 访问量:28

问:

我创建了一个 T4 模板来生成一个分部类。

它引用了我的一个DLL:

<#@ assembly name="$(ProjectDir)..\Base\bin\Debug\net8.0\Base.dll" #>

如果DLL不存在,我的模板会给出错误。我希望它运行没有错误。

如果DLL存在,我想生成一个类并实现它的方法。 如果没有,我想使用空方法生成类。

如何实现这一点?

C# .NET 模板 T4 程序集加载

评论

0赞 Dai 11/15/2023
究竟是什么?当你说“实现它的方法”时,你的意思是你想反映一个或包含在该程序集中?Base.dllinterfaceabstract class
0赞 Dai 11/15/2023
....您知道,更好的方法可能是使用 Roslyn 源生成器
0赞 Dai 11/15/2023
此外,T4 在 VS 的 AppDomain 中运行,这意味着它停留在 .NET Framework 4.8 上,因此您无法可靠地加载构建时执行的程序集 T4(尽管显然这不适用于运行时执行的 T4 模板)net8.0
0赞 just_a_developer 11/15/2023
@Dai我在 Base.dll 中定义了一个属性。我使用该属性来决定如何根据应用了该属性的类生成分部方法。当我说“实现它的方法”时,我的意思是在它们中编写代码
0赞 Dai 11/15/2023
我认为您应该为此使用 Roslyn 而不是 T4。

答:

1赞 Dai 11/15/2023 #1

您需要使用和运行时程序集加载 - using 为从 T4 文件生成的隐式程序集配置编译时程序集引用,如果程序集不存在,这显然不起作用。System.Reflection<#@ assembly

如果DLL不存在,我的模板会给出错误。我希望它运行没有错误。

我看到您正在使用它可以是 MSBuild 参数,或者作为环境变量传递,或者在 T4 中通过访问,或者通过与 VS via 强耦合 - 因此取决于 T4 的执行方式(T4 文件通常在 Visual Studio 中运行,但它们也需要不可用的位置下运行。您需要弄清楚该要求并选择适当的响应。$(ProjectDir)this.HostEnvDTEdotnet buildmsbuidlEnvDTE

除此之外,请执行以下操作:

<#
    DirectoryInfo projectDir = GetProjectDirFromEnvSomehow( /* EnvDTE? this.Host? Environment.GetEnvironmentVariable( "etc" ), etc etc */ );
    FileInfo baseDllFile = new FileInfo( Path.Combine( projectDir.FullName, "Base.dll" ) )

    if( baseDllFile.Exists )
    {
       // See https://learn.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/how-to-load-assemblies-into-the-reflection-only-context
#>
        public class Whatever
        {
<#
            foreach( var member in reflectedMembers ) { this.Write( "public TypeName MemberName { etc; }" ) }
#>
        }
<#

    }
    else
    {
#>
        public class Whatever {}
<#
    }

#>