1

I want to do the following: add a switch in my Web.config and whenever it is turned on, any value coming from a .resx file will appear together with the name of the .resx file it came from. This is mainly for debugging purposes.

My current understanding is that the way to do this is create a custom T4 template, and use it instead of the PublicResXFileCodeGenerator.

I am trying to find a template that does what the PublicResXFileCodeGenerator does, and then build upon that. Is there such a template somewhere in my installation of Visual Studio? If not, can I find such a template from an official source online?

Panos
  • 617
  • 7
  • 20

1 Answers1

3

Visual Studio uses the StronglyTypedResourceBuilder Class to transform .resx files into "hard coded" resources. That's why I don't think there is a similar T4 template somewhere in the Visual Studio installation.

You might want to create your own T4 template. I have no ready-to-use template for your case but this is how I would begin and replace the default resource builder for string resources:

  1. Remove "ResXFileCodeGenerator" from the CustomTool-Property in the resource file's Property Grid.
  2. Delete the existing .Designer.cs file
  3. Add a setting "DebugResources" to the web.config
  4. Open the .resx file inside your T4 template as a XDocument (.resx is an xml format)

    <#@ assembly name="System.Xml" #>
    <#@ assembly name="System.Xml.Linq #>
    <#@ import namespace="System.Xml.Linq #>
    
    <#
       string inputFile = System.IO.Path.GetDirectoryName(this.Host.TemplateFile)
                        + @"\MyResourceFile.resx";
       XDocument resDoc = XDocument.Load(inputFile);
    #>
    
  5. Iterate all elements in the .resx file and generate properties for the resources. Depending on the setting in the web.config add the resource file name to the return value.

    <#
        foreach(var dataElement in resDoc.Descendants("data")
                                         .Where(elem => elem.Attribute("type") == null)
        {
    #>
        public static string <#= dataElement.Attribute("name").Value #> {
          get {
            return ResourceManager.GetString("<#= dataElement.Attribute("name").Value #>")
                   + ((bool.Parse(ConfigurationManager.AppSettings["DebugResources"])) 
                     ? " (MyResourceFile.resx)" 
                     : String.Empty);
    <#
        }
    #>
    
  6. Generate the rest of a resource class: the resource manager (you can copy that from the original Designer.cs file) and check how to deal with Images and other resource types.

Hope this idea helps. Maybe I can come up with a complete and reusable .tt sometime.

Nico
  • 2,120
  • 16
  • 20
  • 1
    Thanks Nico. I wish there was a way to go in the designer files and replace all System.Resources.ResourceManager with my CustomResourceManager that I could derive from ResourceManager. Maybe I can just run a script that I will include in the build. – Panos Jan 31 '13 at 14:53
  • Hm, I agree, that deleting all .designer.cs files might be time consuming and one might forget to delete some. But for the build process it doesn't matter in what file the ResourceManager class is located. Have a look here: http://stackoverflow.com/q/14607395/1990914, this might allow you to actually replace the content of the designer files. – Nico Jan 31 '13 at 15:10