Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using types in a T4 template that exist in the same project as the template

I'm working on my first T4 code generation tool to add some Stored Procedure helper code to my project. I've created custom types (e.g. StoredProcedure and StoredProcedureParameter to help with my code generation and have included the assembly and namespace references in my code:

<#@ template debug="false" hostspecific="false" language="VB" #>
<#@ output extension=".generated.vb" #>
<#@ assembly name="$(TargetPath)" #>
<#@ import namespace="StoredProcCodeGenerator" #>

This allows me to use my custom types in my T4 template code. However, because my custom types exist in the same project as the T4 template code, I can't recompile my project once I run the template code without restarting Visual Studio. This isn't very much fun.

I read a great article that addresses this exact issue by using the T4 Toolbox, but it's not working. Either I'm implementing the VolatileAssembly directive wrong or the T4 toolbox simply didn't get installed. I'm not sure that the toolbox got installed correctly (I'm using VS 2010 on Win XP).

What are some ways that I might be able to fix this problem?

like image 511
Ben McCormack Avatar asked Aug 04 '10 17:08

Ben McCormack


People also ask

What is true about T4 templates in Entity Framework?

T4 templates in entity framework are used to generate C# or VB entity classes from EDMX files. Visual Studio 2013 or 2012 provides two templates- EntityObject Generator and DBContext Generator for creating C# or VB entity classes. The additional templates are also available for download.

What is the purpose of using T4 templates?

Design-time T4 text templates let you generate program code and other files in your Visual Studio project.

What is transform all T4 templates?

t4 is basically a tool built into VS for doing text transformation, typically for doing code generation. Transform All T4 Templates searches your solution for *. tt files and executes them to create other text, again typically source code, files.

How do I add a .TT file to Visual Studio?

Include the file into your Visual Studio project. In Solution Explorer, on the shortcut menu of the project, choose Add > Existing Item. Set the file's Custom Tools property to TextTemplatingFilePreprocessor. In Solution Explorer, on the shortcut menu of the file, choose Properties.


2 Answers

You need to remove the previous assembly reference and then add the VolatileAssembly reference. If you don't remove the regular assembly reference first, you'll get an error that it has already been added when you add the VolatileAssembly reference.

<#@ template debug="false" hostspecific="false" language="VB" #>
<#@ output extension=".generated.vb" #>

<#@ assembly name="$(TargetPath)" #>

<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" 
    name="$(TargetPath)" #>
<#@ import namespace="StoredProcCodeGenerator" #>  

Now you can continue to build your project and use types defined in that project within your T4 templates.

like image 181
Ben McCormack Avatar answered Oct 11 '22 03:10

Ben McCormack


Hopefully this is helpful, it shows a use case of consuming the volatileAssembly, I'm not having any luck getting this t4 template to work at all, but I think it may be helpful:

// <autogenerated/>
// Last generated <#= DateTime.Now #>
<#@ template language="C#" hostspecific="true"#>

<#@ assembly name="System" #>

<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" name="bin\debug\FrameworkWpf.dll" #>
<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" name="bin\debug\FrameworkTestToolkit.dll" #>
<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" name="bin\debug\WpfAppTemplate.exe" #>

<#@ output extension=".cs" #>

<#@ import namespace="System" #>
<#@ import namespace="FrameworkTestToolkit" #>

namespace WpfAppTemplateTest {
 using System;
 using System.Reflection;
<# 
    // Add new types into the below array:
    Type[] types = new Type[] { 
 typeof(FrameworkWpf.SafeEvent),
 typeof(FrameworkWpf.Mvvm.ControllerBase),
 typeof(FrameworkTestToolkit.PrivateAccessorGeneratorTestClass),
 typeof(WpfAppTemplate.PostController),
 typeof(WpfAppTemplate.ShellController),
 };


 // Do not modify this code
 foreach (Type type in types) {
 PrivateAccessorGenerator builder = new PrivateAccessorGenerator(type, WriteLine, Error, Warning);
 builder.Generate();
 }
#>
}

from http://blog.rees.biz/Home/unit-testing-and-private-accessors2

like image 1
Maslow Avatar answered Oct 11 '22 03:10

Maslow