T4 namespace and type resolution

I am trying to create a T4 template that will take my global application resources, iterate over static properties and create a static class with const string attributes, so I could get the resource names as string using a strong type.

Here is what I have now:

 <#@ template debug="true" hostSpecific="true" #> <#@ include file="EF.Utility.CS.ttinclude"#> <#@ output extension=".cs"#> <#@ import namespace="System" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Diagnostics" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Collections" #> <#@ import namespace="System.Collections.Generic" #> <# CodeGenerationTools code = new CodeGenerationTools(this); MetadataLoader loader = new MetadataLoader(this); CodeRegion region = new CodeRegion(this, 1); MetadataTools ef = new MetadataTools(this); string namespaceName = code.VsNamespaceSuggestion(); if (!String.IsNullOrEmpty(namespaceName)) { #> namespace <#=code.EscapeNamespace(namespaceName)#> { <# PushIndent(CodeRegion.GetIndent(1)); } #> public static class ResourceStrings { <# var props = typeof(Resources).GetProperties(BindingFlags.Static); foreach (var prop in props) { #> public const string <#= prop.Name #> = "<#= prop.Name #>"; <# } #> } <# if (!String.IsNullOrEmpty(namespaceName)) { PopIndent(); #> } <# } #> <#+ // Insert any template procedures here #> 

The problem is that it simply cannot find the Resources namespace in typeof() . The Resources namespace is the namespace of my Localize.designer.cs file (Localize.resx auto-generated file).

What am I missing here?

+4
source share
3 answers

I had a similar idea. I wanted to have a static class with constant string values ​​for my user settings in order to use a strong type, not a string in a Windows Forms binding:

 this.textBox1.DataBindings.Add("Text", Properties.Settings.Default, Properties.Settings.PropertyNames.SomeStringValue); 

However, I found out that the t4 template cannot access the types of the current project. You must upload the file using

 <#@ assembly name="$(TargetPath)" #> 

However, if you do this and regenerate your template, you will not rebuild your project, since the file is used if you do not close the visual studio.

Shortly speaking,

I abandoned this approach, and now I myself read the app.config file to get the data I need. It should be fairly easy to modify to read the Resources.xml file.

 <#@ template debug="true" hostspecific="true" language="C#" #> <#@ output extension=".cs" #> <#@ assembly name="System.Core" #> <#@ assembly name="System.Xml" #> <#@ assembly name="System.Xml.Linq" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Xml.Linq" #> <# var xmlFile = Path.Combine(Path.GetDirectoryName(Host.TemplateFile), "..", "app.config"); var query = from x in XElement.Load(xmlFile).Element("userSettings").Element("Your.Namespace.Properties.Settings").Elements("setting") select x; #> namespace Your.Namespace.Properties { public sealed partial class Settings { public static class PropertyNames { <# foreach (var item in query) { #> public static readonly string <#=item.Attribute("name").Value#> = @"<#=item.Attribute("name").Value#>"; <# } #> } } } 
+5
source

Try using T4Toolbox and the Volatile Assembly directive.

 <#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" Name="<Your assembly fully qualified name that you are concerned about locking but need a self reference to>"#> 

It will create a shadow copy of the assembly for use with T4.

To do this, you need to download and install T4Toolbox.

http://t4toolbox.codeplex.com/

+2
source

You can get a link to the current namespace using the following:

 <#+ // other template code here... static string CurrentNamespace = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint").ToString(); 

And use it in your template like this:

 namespace <#=CurrentNamespace #> { public static class MyGenerateClass { // other generated code here... 
+2
source

Source: https://habr.com/ru/post/1338570/


All Articles