How to avoid DLL not found error on T4 template?

76 Views Asked by At

I created a T4 template to generate a partial class.

It references one of my DLLs:

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

If the DLL doesn't exist, my template gives an error. I want it to run without errors.

If the DLL exist, I want to generate a class and implement it's methods. If not, I want to generate the class with empty methods.

How to achieve this?

1

There are 1 best solutions below

0
On

You'll need to use System.Reflection and runtime assembly loading - using <#@ assembly configures a compile-time assembly reference for the implicit assembly generated from your T4 file, which obviously won't work if the assembly doesn't exist.

If the DLL doesn't exist, my template gives an error. I want it to run without errors.

I see you're using $(ProjectDir) which can be an MSBuild parameter, or passed as an environment-variable, or accesed via this.Host in T4, or by being strongly-coupled to VS via EnvDTE - so depending on how the T4 is being executed (T4 files normally run within Visual Studio, but they also need to run under dotnet build or msbuidl where EnvDTE isn't available. You need to figure out that requirement and choose the appropriate response.

But other than that, do something like this:

<#
    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 {}
<#
    }

#>