Generating code files with correct namespaces using T4

The Visual Studio built in Code Generator T4 is mostly used to generate code files. As code in .NET is organized in namespaces I needed a way to figure out the correct namespace for the generated file. T4 provides the ability to access properties of the Host. When using Visual Studio this is the EnvDTE automation object. This gives us access to the project properties that contain a property for the default namespace for the project. But a correct namespace also contains additional parts for each folder inside the solution. Happily the T4 Host property also gives us access to the full path of the template file. So we can interpret the directory. If we now access the EnvDTE automation model again we can also find a project property called FullPath which on the other hand returns us the path to the project file. We replace the project path from the templates files directory, replace the directory separator with a dot and concat the result with the default namespace. Here is the template:

<#@ template debug="false" hostspecific="true" language="C#" #> <#@ output extension=".cs" #> <#@ assembly name="EnvDTE" #> <#@ import namespace="System.IO" #> <# 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; var templateDir = Path.GetDirectoryName(Host.TemplateFile); var fullPath = dteProject.Properties.Item("FullPath").Value.ToString(); fullPath = fullPath.EndsWith("\\") ? fullPath.Substring(0, fullPath.Length-1) : fullPath; var subNamespace = templateDir.Replace(fullPath, string.Empty).Replace("\\", "."); var fileNamespace = string.Concat(defaultNamespace, subNamespace); #> namespace <#= fileNamespace #> { }
Comments are closed