How to output namespace in T4 templates?
Asked Answered
M

6

31

I have a T4 template for a class set up with TextTemplatingFileGenerator Custom Tool in Visual Studio:

<#@ template language="C#v3.5" hostspecific="True" debug="True" #>
<#
  var className = System.IO.Path.GetFileNameWithoutExtension(Host.TemplateFile);
  var namespaceName = "MyNamespace";
#>

namespace <#= namespaceName #>
{
    public static class <#= className #>
    {
        // some generated code
    }
}

How can I get the value of the "Custom Tool Namespace" property in Visual Studio, so I don't have to hardcode the namespace?

I would even be happy with the default namespace for the C# project.

Miniver answered 11/1, 2010 at 14:17 Comment(0)
F
49

If you're using Visual Studio 2010, you can retrieve the namespace by checking the CallContext's "NamespaceHint" property.

System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint");
Foursome answered 4/6, 2010 at 23:54 Comment(7)
Unfortunately, this trick doesn't work when using the MSBuild-based transformation system (as illustrated here: olegsych.com/2010/04/understanding-t4-msbuild-integration). Bummer. :(Concession
This function makes debugging failMajolica
@BradWilson The link seems to be broken.Homerhomere
@venkat Not sure what you're asking of Brad from a seven year old comment.Foursome
@GarethJ - The link (http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration/) mentioned in @BradWilson comment seems to be not working and requesting for alternative links if any exists.Homerhomere
@Venkat, At this point, I think as a community member, you are as capable of using a search engine and providing any more up to date information that's available as the rest of us.Foursome
The article mentioned by Brad can be visualized here : web.archive.org/web/20130805044018/http://www.olegsych.com:80/…Quadrireme
E
15

Here is what you can do with T4 Toolbox:

<#@ template language="C#v3.5" hostspecific="True" debug="True" #> 
<#@ include file="T4Toolbox.tt" #>
<# 
  var namespaceName = TransformationContext.DefaultNamespace; 
#> 

DefaultNamespace property of TransformationContext class returns a string with namespace based on the root namespace of your project and the location of your .tt file in it (i.e. it treats folders as namespaces). This way you don't have to specify Custom Tool Namespace property for every instance of your .tt file.

If you prefer to use the Custom Tool Namespace property, you can pass Host.TemplateFile to the GetCustomToolNamespace method posted by @sixlettervariables.

Edholm answered 12/1, 2010 at 11:47 Comment(3)
I get the error: 'T4Toolbox.TransformationContext' does not contain a definition for 'DefaultNamespace'Symons
Found a fix in this post of yours: olegsych.com/2012/12/t4-toolbox-for-visual-studio-2012Symons
That post is now gone, but the DefaultNamespace appears to now be in the T4Toolbox.ClrTemplate class. (Although the whole project needs updating for VS 2019)Howlyn
C
8

Damien Guard includes some code in a blog posting which retrieves the Custom Tool Namespace for a given file:

public override String GetCustomToolNamespace(string fileName)
{
    return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
}
Chessman answered 11/1, 2010 at 22:48 Comment(0)
C
6

How I've done this:

<#@ assembly name="EnvDTE" #>
<#@ import namespace="EnvDTE" #>

<# 
    // Get value of 'Custom Tool Namespace'
    var serviceProvider = (IServiceProvider)this.Host;
    var dte = (DTE)serviceProvider.GetService(typeof(DTE));    
    var Namespace = dte.Solution.FindProjectItem(this.Host.TemplateFile).Properties.Item("CustomToolNamespace").Value;
 #>

namespace <#= Namespace #> {

}
Considering answered 12/12, 2013 at 13:47 Comment(1)
worked for me; replaced "CustomToolNamespace" with "DefaultNamespace"Tradescantia
D
2

If you use Visual Studio 2012

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint").ToString();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);

Aldo Flores @alduar

Derby answered 20/6, 2013 at 10:0 Comment(0)
S
0

The accepted answer doesn't work on Visual Basic Projects. I had to use the method from: http://lennybacon.com/post/2010/12/10/generatingcodefileswithcorrectnamespacesusingt4

var hostServiceProvider = (IServiceProvider)Host;
var dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
var activeSolutionProjects = (Array)dte.ActiveSolutionProjects;
var dteProject = (EnvDTE.Project)activeSolutionProjects.GetValue(0);
var defaultNamespace = dteProject.Properties.Item("DefaultNamespace").Value;
Sybilla answered 30/9, 2013 at 16:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.