Need access to IDatabaseProjectNode from generic template

Apr 17, 2012 at 8:01 AM

I want to do something like this: "http://www.olegsych.com/2008/03/how-to-generate-multiple-outputs-from-single-t4-template/".

But I can't cast this.Host to IServiceProvider to get DTE object.

So, I decided to implement it.

 

"TFDP.Common" project.

public sealed class TemplateHost

add one member, function and property:

private IDatabaseProjectNode project;
internal void SetProject(IDatabaseProjectNode project)
{
 this.project = project;
}
public IDatabaseProjectNode Project
{
 get
 {
  return this.project;
 }
}

 

Next is:

public sealed class GenericTemplateProcessor

Add one function:

public void SetProject(IDatabaseProjectNode project)
{
 this.templateHost.SetProject(project);
}

And finally, project "TFDP.VsPackage"

public class ProjectManager : IDisposable, IDatabaseProjectIdleProcessor

At the end of InitializeGenericProcessor function add one row:

private void InitializeGenericProcessor()
{
 ...

 genericProcessor.SetProject(project);
}

 

 DONE!

 

Now in your template you can write this one:

File.WriteAllText(outputFilePath, this.GenerationEnvironment.ToString());
this.GenerationEnvironment = new StringBuilder();
var vsProject = (this.Host as TFDP.Common.T4.TemplateHost).Project;
var vsTemplateNode = vsProject.FindNode(this.Host.TemplateFile);
IDatabaseFileNode outputNode = (IDatabaseFileNode)vsProject.FindNode(outputFilePath);
if (outputNode == null)
 vsProject.CreateFileNode(vsTemplateNode.ParentNode, outputFilePath, out outputNode);

 

The End!

Coordinator
Apr 17, 2012 at 9:16 AM
Edited Apr 17, 2012 at 9:16 AM

There is an easier way to do this: 

var tempFileName = @"c:\temp\foo.txt";
var targetFileName = "SomeFile.sql";
var artifact = new GeneratedArtifact(tempFileName, targetFileName);
var host = this.Host as TemplateHost;
host.AddArtifact(artifact);

The extension will handle the heavy lifting of checking-out and adding it to the project. This will work either in a "normal" template as well as in templates that derive from DatabaseTemplate.

Hope this helps, if you've got any other questions I'd like to hear from you!

Apr 17, 2012 at 1:08 PM
Edited Apr 17, 2012 at 1:09 PM

Yes it works. But:

1. It add generated file to the project only after unload/reload.

2. I can't generate multiple files from one template.

Coordinator
Apr 17, 2012 at 2:14 PM

Ah, it should, even for multiple files.

I'll look in to it tonight.