Passing parameters to Templates when programmatically generating code<p>Hi,</p> <p>I am generating code within a GAT project using T4 and a DSL. Since I need a fine level of control, I have implemented an Action that takes care of the code generation programmatically. </p> <p>I am wondering how I can pass a parameter to a T4 template in this case?</p> <p>Here is a snippet of my Action so you can get an idea of how I'm achieving this so far.</p> <p>Thanks,</p> <p>Scott.</p> <p> </p><font size=2> <p></font><font color="#0000ff" size=2>public</font><font size=2> </font><font color="#0000ff" size=2>override</font><font size=2> </font><font color="#0000ff" size=2>void</font><font size=2> Execute()</p> <p>{</p> <p>MyModeller.ModelRoot root;</p> <p></font><font color="#0000ff" size=2>string</font><font size=2> template;</p> <p></font><font color="#0000ff" size=2>string</font><font size=2> templateOutput;</p> <p></font><font color="#0000ff" size=2>string</font><font size=2> dslLocation;</p> <p></p> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p></font><font color="#008000" size=2>// Get a reference to the T4 Templating engine</p></font><font size=2> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p>ITextTemplating templateGen = (ITextTemplating) Package.GetGlobalService(</font><font color="#0000ff" size=2>typeof</font><font size=2>(STextTemplating));</p> <p></p> <p>dslLocation = &lt;dsl_location&gt;;</p> <p></p> <p></font><font color="#0000ff" size=2>if</font><font size=2> (templateGen != </font><font color="#0000ff" size=2>null</font><font size=2>)</p> <p>{ </p> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p></font><font color="#008000" size=2>// Generate Code. Execute the template for each Class in the model</p></font><font size=2> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p></font><font color="#0000ff" size=2>using</font><font size=2> (Store store = </font><font color="#0000ff" size=2>new</font><font size=2> Store())</p> <p>{</p> <p>store.LoadDomainModels(</font><font color="#0000ff" size=2>typeof</font><font size=2>(CoreDesignSurfaceDomainModel), </font><font color="#0000ff" size=2>typeof</font><font size=2>(MyModeller.MyModellerDomainModel));</p> <p></font><font color="#0000ff" size=2>using</font><font size=2> (Transaction t = store.TransactionManager.BeginTransaction(</font><font color="#800000" size=2>&quot;LoadModel&quot;</font><font size=2>))</p> <p>{</p> <p><font color="#008000">// Load the Model</font></p> <p>root = MyModeller.MyModellerSerializationHelper.Instance.LoadModel(store, dslLocation, </font><font color="#0000ff" size=2>null</font><font size=2>, </font><font color="#0000ff" size=2>null</font><font size=2>);</p> <p></p> <p></font><font color="#0000ff" size=2>foreach</font><font size=2> (MyModeller.ModelClass type </font><font color="#0000ff" size=2>in</font><font size=2> root.Types)</p> <p>{</p> <p>template = GetFromResources(&lt;my_embedded_template2&gt;);</p> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p></font><font color="#008000" size=2>// *** HOW DO I PASS 'type' as a parameter to this template??</p></font><font size=2> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p>templateOutput = templateGen.ProcessTemplate(</font><font color="#800000" size=2>&quot;c:\\temp\\dummy.txt&quot;</font><font size=2>, template, </font><font color="#0000ff" size=2>null</font><font size=2>, </font><font color="#0000ff" size=2>null</font><font size=2>);</p> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p></font><font color="#008000" size=2>// Add the output to the solution</p></font><font size=2> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p>AddTemplateToSpecificFileInSolution(templateOutput);</p> <p>}</p> <p>}</p> <p>} </p> <p>}</p> <p>}</p></font>© 2009 Microsoft Corporation. All rights reserved.Thu, 19 Jun 2008 00:15:52 Z5e84c042-467d-4430-b9ac-85f1397d8967http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/5e84c042-467d-4430-b9ac-85f1397d8967#5e84c042-467d-4430-b9ac-85f1397d8967http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/5e84c042-467d-4430-b9ac-85f1397d8967#5e84c042-467d-4430-b9ac-85f1397d8967Scott Simmshttp://social.msdn.microsoft.com/Profile/en-US/?user=Scott%20SimmsPassing parameters to Templates when programmatically generating code<p>Hi,</p> <p>I am generating code within a GAT project using T4 and a DSL. Since I need a fine level of control, I have implemented an Action that takes care of the code generation programmatically. </p> <p>I am wondering how I can pass a parameter to a T4 template in this case?</p> <p>Here is a snippet of my Action so you can get an idea of how I'm achieving this so far.</p> <p>Thanks,</p> <p>Scott.</p> <p> </p><font size=2> <p></font><font color="#0000ff" size=2>public</font><font size=2> </font><font color="#0000ff" size=2>override</font><font size=2> </font><font color="#0000ff" size=2>void</font><font size=2> Execute()</p> <p>{</p> <p>MyModeller.ModelRoot root;</p> <p></font><font color="#0000ff" size=2>string</font><font size=2> template;</p> <p></font><font color="#0000ff" size=2>string</font><font size=2> templateOutput;</p> <p></font><font color="#0000ff" size=2>string</font><font size=2> dslLocation;</p> <p></p> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p></font><font color="#008000" size=2>// Get a reference to the T4 Templating engine</p></font><font size=2> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p>ITextTemplating templateGen = (ITextTemplating) Package.GetGlobalService(</font><font color="#0000ff" size=2>typeof</font><font size=2>(STextTemplating));</p> <p></p> <p>dslLocation = &lt;dsl_location&gt;;</p> <p></p> <p></font><font color="#0000ff" size=2>if</font><font size=2> (templateGen != </font><font color="#0000ff" size=2>null</font><font size=2>)</p> <p>{ </p> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p></font><font color="#008000" size=2>// Generate Code. Execute the template for each Class in the model</p></font><font size=2> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p></font><font color="#0000ff" size=2>using</font><font size=2> (Store store = </font><font color="#0000ff" size=2>new</font><font size=2> Store())</p> <p>{</p> <p>store.LoadDomainModels(</font><font color="#0000ff" size=2>typeof</font><font size=2>(CoreDesignSurfaceDomainModel), </font><font color="#0000ff" size=2>typeof</font><font size=2>(MyModeller.MyModellerDomainModel));</p> <p></font><font color="#0000ff" size=2>using</font><font size=2> (Transaction t = store.TransactionManager.BeginTransaction(</font><font color="#800000" size=2>&quot;LoadModel&quot;</font><font size=2>))</p> <p>{</p> <p><font color="#008000">// Load the Model</font></p> <p>root = MyModeller.MyModellerSerializationHelper.Instance.LoadModel(store, dslLocation, </font><font color="#0000ff" size=2>null</font><font size=2>, </font><font color="#0000ff" size=2>null</font><font size=2>);</p> <p></p> <p></font><font color="#0000ff" size=2>foreach</font><font size=2> (MyModeller.ModelClass type </font><font color="#0000ff" size=2>in</font><font size=2> root.Types)</p> <p>{</p> <p>template = GetFromResources(&lt;my_embedded_template2&gt;);</p> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p></font><font color="#008000" size=2>// *** HOW DO I PASS 'type' as a parameter to this template??</p></font><font size=2> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p>templateOutput = templateGen.ProcessTemplate(</font><font color="#800000" size=2>&quot;c:\\temp\\dummy.txt&quot;</font><font size=2>, template, </font><font color="#0000ff" size=2>null</font><font size=2>, </font><font color="#0000ff" size=2>null</font><font size=2>);</p> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p></font><font color="#008000" size=2>// Add the output to the solution</p></font><font size=2> <p></font><font color="#008000" size=2>//</p></font><font size=2> <p>AddTemplateToSpecificFileInSolution(templateOutput);</p> <p>}</p> <p>}</p> <p>} </p> <p>}</p> <p>}</p></font>Fri, 20 Oct 2006 03:56:01 Z2007-01-18T17:53:18Zhttp://social.msdn.microsoft.com/Forums/en-US/vsx/thread/5e84c042-467d-4430-b9ac-85f1397d8967#8df7307f-2190-4db5-b42e-4cd23b96dafehttp://social.msdn.microsoft.com/Forums/en-US/vsx/thread/5e84c042-467d-4430-b9ac-85f1397d8967#8df7307f-2190-4db5-b42e-4cd23b96dafeGokhan Altinorenhttp://social.msdn.microsoft.com/Profile/en-US/?user=Gokhan%20AltinorenPassing parameters to Templates when programmatically generating codeHi Scott,<br><br>You may do a string replace on &quot;template&quot; variable. Define a placeholder variable in you template and replace it before calling ProcessTemplate.<br><br>I use the code below in a Custom Tool, not exactly the same with your code but the same approach.<br><br>internal class ActiveWriterTemplatedCodeGenerator : TemplatedCodeGenerator<br>    {<br>        protected override byte[] GenerateCode(string inputFileName, string inputFileContent)<br>        {<br>            ResourceManager manager =<br>                new ResourceManager(&quot;Altinoren.ActiveWriter.VSPackage&quot;,<br>                                    typeof (ActiveWriterTemplatedCodeGenerator).Assembly);<br>            FileInfo fi = new FileInfo(inputFileName);<br>            inputFileContent =<br>                manager.GetObject(&quot;ActiveWriterReport&quot;).ToString().Replace(&quot;%MODELFILE%&quot;, fi.Name).Replace(<br>                    &quot;%NAMESPACE%&quot;, FileNameSpace).Replace(&quot;%EXT%&quot;, &quot;cs&quot;); // TODO: Get file extension from the project model<br><br>            byte[] data = base.GenerateCode(inputFileName, inputFileContent);<br>            return data;<br>        }<br>    }<br><br>and the template<br><br>&lt;#@ template inherits=&quot;Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation&quot; debug=&quot;true&quot;#&gt;<br>&lt;#@ output extension=&quot;.%EXT%&quot; #&gt;<br>&lt;#@ ActiveWriter processor=&quot;ActiveWriterDirectiveProcessor&quot; requires=&quot;fileName='%MODELFILE%'&quot; #&gt;<br>&lt;#@ import namespace=&quot;Altinoren.ActiveWriter.CodeGeneration&quot; #&gt;<br>&lt;#<br>    CodeGenerationHelper helper = new CodeGenerationHelper(this.Model, &quot;%NAMESPACE%&quot;);<br>    this.Write(helper.Generate());<br>#&gt;:<br>Fri, 20 Oct 2006 06:31:04 Z2006-10-20T06:31:04Zhttp://social.msdn.microsoft.com/Forums/en-US/vsx/thread/5e84c042-467d-4430-b9ac-85f1397d8967#4dc108bc-088d-4159-b65a-506c6ab4d224http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/5e84c042-467d-4430-b9ac-85f1397d8967#4dc108bc-088d-4159-b65a-506c6ab4d224Scott Simmshttp://social.msdn.microsoft.com/Profile/en-US/?user=Scott%20SimmsPassing parameters to Templates when programmatically generating code<p>I was thinking of the situation where you have parameters defined in a template like:</p> <p>&lt;#@ property processor=&quot;PropertyProcessor&quot; name=&quot;MyParameter&quot; type=&quot;MyType&quot; #&gt;</p> <p>... and you want to programmatically supply the parameters from an Action.</p> <p>Thanks,</p> <p>Scott</p> <p> </p> <p> </p> <p> </p>Fri, 20 Oct 2006 08:27:01 Z2006-10-20T08:27:01Zhttp://social.msdn.microsoft.com/Forums/en-US/vsx/thread/5e84c042-467d-4430-b9ac-85f1397d8967#24ea2c68-742d-4f04-ba51-57ec5d649378http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/5e84c042-467d-4430-b9ac-85f1397d8967#24ea2c68-742d-4f04-ba51-57ec5d649378Gokhan Altinorenhttp://social.msdn.microsoft.com/Profile/en-US/?user=Gokhan%20AltinorenPassing parameters to Templates when programmatically generating codeI might be getting you wrong but, you already got the model loaded by the DirectiveProcessor in your template, right? (Assuming that GAT also provides the processor for your model. I know little about GAT) In the template, you can replace some %ID% placeholder with the ID of the &quot;type&quot;, enumerate the loaded model, find your ModelClass with the %ID% supplied and process as you like.<br><br>If you absolutely need your property ready to use at the begining, you can write a custom directive processor to load your model and supply a specific object, inherited from RequiresProvidesDirectiveProcessor, but you will still need to supply a hint to find your desired class instance from the model. <span id="_ctl0_MainContent_PostFlatView"><span></span><br><br>You may want to look at <a title="http://msdn2.microsoft.com/en-us/library/aa397875.aspx" href="http://msdn2.microsoft.com/en-us/library/aa397875.aspx">http://msdn2.microsoft.com/en-us/library/aa397875.aspx</a> for usage. There's also a sample @<br>C:\Program Files\Visual Studio 2005 SDK\2006.09\VisualStudioIntegration\Samples\DSLTools\Example.TextTemplating\Example.TextTemplating.DirectiveProcessors<br>if you have the SDK installed.<br><br>Gokhan<br></span>Fri, 20 Oct 2006 22:23:15 Z2007-01-18T17:53:18Z