I'm trying to create T4 template that will take my app global Resources, loop through the static properties and create a static class with const string
properties, so I would be able to get resource names as string
by using the strong type.
Here's 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 just can't find the Resources
namespace in the typeof()
. The Resources
namespace is the namespace of my Localize.designer.cs file (autogenerated file of Localize.resx).
What am I missing here?
I just had a similar idea. I wanted to have a static class with const string values for my user settings in order to use a strong type rather than a string in Windows Forms Binding:
this.textBox1.DataBindings.Add("Text", Properties.Settings.Default, Properties.Settings.PropertyNames.SomeStringValue);
However, I figured out that a t4 template cannot access the types of the current project. You have to load the file with
<#@ assembly name="$(TargetPath)" #>
However, if you do that and regenerate your template you not rebuild your project since the file is in use unless you close visual studio.
Long story short,
I dropped this approach and now I read the app.config file by myself to get the data I need.
Should be quite easy to modify to read the Resources.xml
file instead.
<#@ 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#>";
<# } #>
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With