Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I reference classes in a T4 text template that already exist in the current project?

Tags:

c#

c#-4.0

t4

I'm trying to use the T4 template to auto-generate some code use in my project. I started small to get my 'feet wet' and this is what I have so far.

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="C:\Users\username\Documents\Visual Studio 2012\Projects\MyProjectSolution\MyProject\bin\Debug\MyProject.exe" #>
namespace KY_ADJRATE_CLAIM
{
    public class OutboundClaim
    {
<#
    ClaimConfig cc;
 #>
    }
}

I've tried this

<#@ assembly name="C:\Users\username\Documents\Visual Studio 2012\Projects\MyProjectSolution\MyProject\bin\Debug\MyProject.exe" #>

and this

<#@ assembly name="MyProject.exe" #>

But everytime I try to create an instance of one of my classes, I get this:

A namespace cannot directly contain members such as fields or methods. Compiling transformation: The type or namespace name 'ClaimConfig' could not be found (are you missing a using directive or an assembly reference?)

What I want to do is access the ClaimConfig class in my project through a T4 template.

Any help would be greatly appreciated.

like image 725
Andy Evans Avatar asked Dec 16 '22 05:12

Andy Evans


2 Answers

This is similar to another question I've seen in the past (How do I use custom library/project in T4 text template?). You need to reference the DLL using the "assembly" directive. For instance:

<#@ assembly name=“System.Xml” #>

In order to reference a DLL from your own project or solution, you can use a relative path, but first you'll have to set the HostSpecific attribute in the "template" directive like this:

<#@ template language="C#" debug="false" hostspecific="true" #>

You can then use the $(SolutionDir) macro to get the root of the solution, and construct a relative path to the DLL from there, like this:

<#@ assembly name="$(SolutionDir)\MyOtherProject\bin\Debug\MyOtherAssembly.dll” #>
like image 133
Mel Avatar answered Jan 25 '23 23:01

Mel


I strongly suggest that you separate all common classes (this is, classes that will be used in T4 and outside T4) in a common assembly, which can then be referenced by your project and your T4 Templates:

 MySolution
 |
 | -> MyProject.Common
 |    |--> ClaimConfig.cs
 | 
 | -> MyProject.Main
 |    |--> References
 |    |    |--> MyProject.Common
 |    | MyT4Template.tt

So that the compilation of MyProject.Common (which contains all classes needed to successfully compile the Main project AND the T4 Templates) is separated.

Then in your template:

<#@ assembly name="C:\Users\username\Documents\Visual Studio 2012\Projects\MyProjectSolution\MyProject.Common\bin\Debug\MyProject.Common.dll" #>

Also, I strongly suggest you use a T4 Editor, such as Tangible T4 Editor, it's going to help you A LOT when editing T4 templates, mainly because it clearly highlights and makes a visual difference between "resulting code" (I.E the template output) and "generating code" (the code inside the template). They provide a free version, as well as a commercial full version. I use the free version and it has been really helpful so far.

like image 37
Federico Berasategui Avatar answered Jan 25 '23 23:01

Federico Berasategui