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.

Hallgrim
  • 15,143
  • 10
  • 46
  • 54

6 Answers6

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");
GarethJ
  • 6,496
  • 32
  • 42
  • 2
    Unfortunately, this trick doesn't work when using the MSBuild-based transformation system (as illustrated here: http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration/). Bummer. :( – Brad Wilson Aug 17 '13 at 04:24
  • This function makes debugging fail – johnny 5 May 01 '17 at 20:10
  • @BradWilson The link seems to be broken. – Venkat Feb 12 '20 at 11:34
  • @venkat Not sure what you're asking of Brad from a seven year old comment. – GarethJ Feb 21 '20 at 06:50
  • `@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. – Venkat Feb 21 '20 at 08:48
  • @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. – GarethJ Mar 17 '20 at 23:10
  • 1
    The article mentioned by Brad can be visualized here : https://web.archive.org/web/20130805044018/http://www.olegsych.com:80/2010/04/understanding-t4-msbuild-integration/ – Glaerferyn Apr 28 '23 at 13:36
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.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Oleg Sych
  • 6,548
  • 36
  • 34
  • I get the error: 'T4Toolbox.TransformationContext' does not contain a definition for 'DefaultNamespace' – Thomas Stock Apr 04 '14 at 08:59
  • 1
    Found a fix in this post of yours: http://www.olegsych.com/2012/12/t4-toolbox-for-visual-studio-2012/ – Thomas Stock Apr 04 '14 at 09:25
  • 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) – Ann L. Jan 21 '21 at 14:12
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();
}
user7116
  • 63,008
  • 17
  • 141
  • 172
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 #> {

}
Damian Drygiel
  • 17,900
  • 4
  • 35
  • 28
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

alduar
  • 71
  • 1
  • 5
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;
Nick Prince
  • 413
  • 3
  • 9