Template creation question

Jan 31, 2009 at 10:29 PM


I would like to ask you, if it is possible to generate files from the templates, and create them in other subdirectories of the project, not the same folder as the starting template exists. Also if it is possible to make the new files, have the "Build Action" and "Copy to Output Directory" properties, defined at the time of the file generation. The combination of these two features, would help the creation of text resource files that could be embedded in a project during the build process...

George J.

Feb 1, 2009 at 12:14 AM

Yes, it is technically possible to do all of the things you asked about using Visual Studio extensibility APIs. No, T4 Toolbox doesn't make it easier. Here are some challenges I would like your opinion on.

Generating files in other folders

In T4 Toolbox, TransformationContext manages generated output files. All files nested under the .tt file are assumed to be generated. In the end of code generation, TransformationContext simply removes any files that weren’t regenerated. This automatically removes output files that are no longer necessary.

Unfortunately, I haven’t found a way to do this for files in other folders. One idea was to use links to the generated files, but there appears to be no way to have the links nested under the main .tt file. Another idea was to use custom file properties in the Visual Studio project to store the list of generated files, but there seems to be no way to do that either.


The only feasible solution I can think of is to use the main output of the .tt file as a log file to store the list of all generated files. TransformationContext would read this list from the file in the beginning of code generation, save generated files to their respective folders and remove any files that were not regenerated from the project and finally save the new list to the log file (i.e. write it to the main output of the .tt file).

Setting "Build Action", "Copy to Output Directory" and other properties

I think it would be possible to set these properties via EnvDTE.ProjectItem.Properties collection. I've used it to set "Custom Tool" property successfully in the LINQ to SQL generator. How would you like to set these in a T4 code? I was thinking something along the lines:

MyTemplate template = new MyTemplate();
template.ClassName = "MyClass"; // made up custom code generation parameter
template.BuildAction = "Compile";
template.CopyToOutputDirectory = Copy.IfNewer;
template.OutputFile = () => "SubFolder\" + template.ClassName + ".cs";


Feb 1, 2009 at 8:19 AM
The feature that TransformationContext provides it too nice to break. Although, you could provide an option - a property, perhaps - that would allow to define the output paths of the generated files and disable that feature. Eg. the property is called CreateNestedFiles and by default is true and the generated files are nested under the template, and TransformationContext checks which files are created in order to clean-up. When the property is changed to false, the path of the generated files is the combination of the project path and the path provided in the generation call - the parameter passed to RenderFile(). Many third party tools (e.g. Resharper) add a hidden resource file in the project, that keep data they need. You could write the output log there, in order to do the clean-up.

I think the example code you provided provides all the necessary functionality needed. BuildAction could also be provided as an enumeration.

George J.