Please not another NullReference

I’m just sitting in front of a piece of code. Only about 30 lines long it contains more than 10 checks for null values. It is barely readable even after I combined some of these checks into methods with meaningful names. I don’t dare to think about what any complexity metric would tell me about it 😦

I know that inventing the Null Reference was one of the biggest mistakes in the history of computer science. But just because I know that doesn’t help me much when dealing with the aftermath of that mistake on a daily basis.

There are a few things that help though.

Never return null!

Your methods should never ever in any case return null! Ever! I mean it!

For strings there is string.Empty.

For enumerations there is Enumerable.Empty<T>() or the empty array T[0]. If you use lists or collections (preferably represented by their respective interfaces) there is the (newly created) empty list.

For infrastructure components there is always some implementation of the NullObject Pattern (think about a NullLogger that does not write anything anywhere).

For data objects you can define an Empty property that contains an object that is valid in the sense of “I’m valid by the rules of your programming language” but that is defined as invalid by your business rules (think in terms of Guid.Empty). Make sure to enforce the use of these properties. In addition to anything else it will make your code more readable.

For numeric IDs you should define a lower threshold for what is valid and what not. Usually IDs that are less than or equal to zero are not valid. They are just the default that .NET assigns to numeric types. Make that decision explicit! That way it is safe to check for invalid IDs anywhere you use them.

Oh and while I’m at it: Don’t throw NullReferenceExceptions when validating the parameters of a method. Use Guard classes that throw ArgumentNullExceptions or Code Contracts that throw their own special type of exception. NullReferenceExceptions are system exceptions and should stay that way.

Advertisements

Custom resources with T4

Resource files are an old hat in .NET. They have been around since v1.1 and are one popular way to localize strings in an application.

Visual Studio provides two built-in tools (namely PublicResXFileCodeGenerator and ResXFileCodeGenerator) that generate code from the *.resx files. They generate classes with different visibility (public vs. internal) but the result is otherwise the same. You get a property to get and set the culture of the resource (to override the usage of the current UI culture), a hardwired instance of the framework’s ResourceManager and a bunch of static properties that forward the call to their getter to the ResourceManager. Nothing truly spectacular so far.

The ResourceManager takes care of the hassles of getting the correct version of your resources out of the files and the static properties allow for very convenient usage throughout your application. Alas, life could be so easy if customers were satisfied with that scenario. But they want to be able to customize their application (preferably without the involvement of a developer) to fit the corporate identity, use established vocabulary etc. pp.

Hard-wired static classes just don’t fit those customer requirements. But I believe they are a very good first step on the way if you could just tweak them a bit.

Unfortunately you cannot do anything to make those classes any more flexible. They are not partial. The creation of and the access to the ResourceManager is out of your reach. You get what the tools give you. Nothing more and nothing less. As I did not want to go through the painful process of writing a custom extension for VS I looked for a different approach. And found the Text Template Transformation Toolkit (T4).

I even found a tutorial on CodeProject that explains how to do what I wanted to achieve. I just wanted my result to look a little different.

What were my requirements?

  • Static properties for convenient access to the localized resources
  • Allow to replace the ResourceManager by editing the template
  • Allow to replace the ResourceManager at runtime via settable property
  • Avoid the complexity of overwriting the virtual methods of ResourceManager

Lets start from the last requirement. The ResourceManager class has way to much functionality for my liking even if most of that functionality seems to be accessible to derived types via virtual methods. So I decided to create a very simple interface that contains the only method that is used by the generated resource classes.

public interface IResourceManager
{
  string GetString(string name, CultureInfo culture);
}

An equally simple adapter from interface to the framework class allows me to use the default ResourceManager.

public class ResourceManagerWrapper : IResourceManager
{
  private readonly ResourceManager resourceManager;

  public ResourceManagerWrapper(ResourceManager resourceManager)
  {
    this.resourceManager = resourceManager;
  }

  public string GetString(string name, CultureInfo culture)
  {
    return this.resourceManager.GetString(name, culture);
  }
}

I added a setter to the static ResourceManager property and changed its type to IResourceManager. And finally I added a fallback to the default ResourceManager in case someone sets the property to null. The result is functionally identical to the code that VS generates but looks less generated. But that’s a matter of taste. Below is a sample of the generated output.

public class Labels
{
  private static IResourceManager resourceManager;
  private static CultureInfo resourceCulture;

  [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
  public static IResourceManager ResourceManager
  {
    get
    {
      if(resourceManager == null)
      {
        IResourceManager temp = new ResourceManagerWrapper(new ResourceManager("Main.Assets.Resources.Labels", typeof(Labels).Assembly));
        resourceManager = temp;
      }
      return resourceManager;
    }
    set
    {
      resourceManager = value;
    }
  }
  [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
  public static CultureInfo Culture
  {
    get
    {
      return resourceCulture;
    }
    set
    {
      resourceCulture = value;
    }
  }
  public static string MyMultiLanguageString
  {
    get { return ResourceManager.GetString("MyMultiLanguageString", resourceCulture ?? CultureInfo.CurrentUICulture); }
  }
}

That was the boring part I guess. The actual template file being the more interesting one.

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.34003
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
<#@ template hostspecific="true" language="C#" #>
<#@ output extension=".Designer.cs" #>
<#@ assembly name="EnvDTE" #>
<#@ assembly name="System.IO" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Xml.Linq" #>

namespace Main.Assets.Resources
{
    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.Resources;
    using System.Threading;
    using Infrastructure.I18n;

    public class Labels
    {
        private static IResourceManager resourceManager;
        private static CultureInfo resourceCulture;

        [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
        public static IResourceManager ResourceManager
        {
            get
            {
                if(resourceManager == null)
                {
                    IResourceManager temp = new ResourceManagerWrapper(new ResourceManager("Main.Assets.Resources.Labels", typeof(Labels).Assembly));
                    resourceManager = temp;
                }

                return resourceManager;
            }

            set
            {
                resourceManager = value;
            }
        }

        [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
        public static CultureInfo Culture
        {
            get
            {
                return resourceCulture;
            }

            set
            {
                resourceCulture = value;
            }
        }
<#
    string resxFileName = this.Host.TemplateFile.Replace(".tt", ".resx");
    XDocument doc = XDocument.Load(resxFileName);

    if(doc != null && doc.Root != null)
    {
        foreach(XElement x in doc.Root.Descendants("data"))
        {
            string name = x.Attribute("name").Value;
            WriteLine(string.Empty);
            WriteLine("        public static string " + name);
            WriteLine("        {");
            WriteLine("            get { return ResourceManager.GetString(\"" + name + "\", resourceCulture ?? CultureInfo.CurrentUICulture); }");
            WriteLine("        }");
        }
    }
#>
    }
}

One thing to notice is that the namespace for the generated file is hardcoded in the template. This has several reasons.

While T4 is an awesome idea, MS managed to mess it up (as usual you might add). There is a VS implementation of ITextTemplatingHostEngine (which allows you to debug your template from the solution explorer. +1 for that feature!) and one for MSBuild (which does not support debugging as far as I found out). Those implementations are your entry point into the VS API from inside a template. As you might expect: They have just enough subtle differences to screw you up… Getting the correct namespace for a file is just one of them.

Another thing is that I decided to go with one template per *.resx file. You can enhance the template and locate all input files for code generation in your solution and compute the output destination and… I wanted a simple solution so I did not go that route.

And last but not least: I use ReSharper’s Multifile Templates to create new *.resx files. That gives me the resources and the templates in a single step. ReSharper has a macro to insert the default namespace of a project into the template file. I have a convention for the folder structure in which I place resource files so I can just append that to the namespace an be done with it.

And the really, really last thing I want to mention before I finish this post: You can hook up the generation process of your templates to MSBuild (which is the reason I noticed the differences between the VS and the MSBuild template engine). That way you can be sure that your build always uses the latest generated resource code and avoid the error prone step of manually calling “Run custom tool” after you made changes to a *.resx files. Oleg Sych collected a lot of information related to T4 in his blog.