Search code examples
c#visual-studio-2010code-generationt4

Cannot reference dependency assemblies in T4 template when using TransformOnBuild


We're trying to use T4 with Visual Studio 2010 (SP1) to build scripts for another language that are based upon some of our existing C# classes. I'm hoping for the following:

  1. The template needs to load our existing assembly and use objects from a namespace in that assembly.
  2. The transformation needs to run on every build on every development machine and build server without any additional installations.
  3. (1) and (2) need to work together.

(1) was fairly straightforward:

<#@ assembly name="$(TargetDir)RequiredProject.dll" #>
<#@ import namespace="RequiredProject.RequiredNamespace" #>

Using the $(TargetDir) macro allowed me to reference the dll with a fully qualified UNC path (per the instructions found here).

(2) is a bit roundabout, but I think I've got it solved: I installed the required text transformation SDKs on a different machine and copied the required .targets and .dlls into a folder in my solution and then updated my .csproj file to reference the local .targets file.

(3) is where I run into problems. It seems like the <TransformOnBuild>true</TransformOnBuild> property doesn't play nicely when a referenced assembly needs to be built prior to the transformation. Everytime I enable transform on build with referenced assemblies, I get the following error:

Compiling transformation: Metadata file '$(TargetDir)RequiredProject.dll' could not be found.

However, I'm using the same assembly instruction that I was using in (1) to reference the assembly. In fact, going to the .tt template directly and saving it still produces the expected output -- it just doesn't work during the "build" step. Am I doing something wrong, or is there a way to ensure that the template transformations occur after the assemblies they depend on are built? (Or, more simply, that template transformations occur last?)


Solution

  • Unfortunately, the msbuild T4 host doesn't yet support embedded macro or msbuild variables in assembly names.

    However, it does support Windows environment variables "%foo%", so although it means some machine-level setup, you can get something that works across in-IDE and build time transforms.