How to output namespace in T4 templates?

2020-02-18 11:24发布

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.

6条回答
你好瞎i
2楼-- · 2020-02-18 11:53

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();
}
查看更多
The star\"
3楼-- · 2020-02-18 11:59

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.

查看更多
闹够了就滚
4楼-- · 2020-02-18 12:04

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");
查看更多
beautiful°
5楼-- · 2020-02-18 12:12

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 #> {

}
查看更多
Evening l夕情丶
6楼-- · 2020-02-18 12:14

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

查看更多
Lonely孤独者°
7楼-- · 2020-02-18 12:16

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;
查看更多
登录 后发表回答