2015 in review

The WordPress.com stats helper monkeys prepared a 2015 annual report for this blog.

Here’s an excerpt:

A New York City subway train holds 1,200 people. This blog was viewed about 7,500 times in 2015. If it were a NYC subway train, it would take about 6 trips to carry that many people.

Click here to see the complete report.

Quartz.NET meets Design Patterns

This is the third in a series of posts.

In the last post I showed you how I set up some tests for my implementation of retries with Quartz.NET. I repeatedly hinted at some neat tricks to make things more convenient so here they are.

Quartz.NET requires that your jobs only throw JobExecutionExceptions (as explained at the very bottom of this page). There are reasons why this restriction makes sense but I don’t want to litter my business logic with repetitions of the exact same exception handling code. I think that’s what DRY is all about. I don’t want to force all of my jobs to inherit from a specific base class either. At least not for the single purpose of following Quartz.NET’s rules for exception handling.

But by applying a decorator to my job classes I can fix that once and for all.

public class EnsureJobExecutionExceptionDecorator : IJob
{
  private readonly IJob inner;
  public EnsureJobExecutionExceptionDecorator(IJob inner)
  {
    this.inner = inner;
  }
  public void Execute(IJobExecutionContext context)
  {
    try
    {
      this.inner.Execute(context);
    }
    catch (JobExecutionException)
    {
      throw;
    }
    catch (Exception cause)
    {
      throw new JobExecutionException(cause);
    }
  }
}

JobExecutionExceptions are simply rethrown. Which allows you to throw them in your job if you have to tweak what to tell the scheduler. All other exceptions become InnerExceptions of a new JobExecutionException. Done. Now that was easy.

But how do I ensure that each time Quartz.NET instantiates a job the decorator is in place?

By replacing the scheduler’s default IJobFactory with something more advanced. For my playground I derived from the PropertySettingJobFactory base class and use Unity to create my jobs.

private sealed class UnityJobFactory : PropertySettingJobFactory
{
  private readonly IUnityContainer container;
  public UnityJobFactory(IUnityContainer container)
  {
    this.ThrowIfPropertyNotFound = false;
    this.WarnIfPropertyNotFound = true;
    this.container = container;
  }
  public override IJob NewJob(
    TriggerFiredBundle bundle,
    IScheduler scheduler)
  {
    Type jobType = bundle.JobDetail.JobType;
    IJob job = (IJob)this.container.Resolve(jobType);
    JobDataMap data = new JobDataMap();
    data.PutAll(scheduler.Context);
    data.PutAll(bundle.JobDetail.JobDataMap);
    data.PutAll(bundle.Trigger.JobDataMap);
    this.SetObjectProperties((object)job, data);
    return job;
  }
  public override void ReturnJob(IJob job)
  {
    this.container.Teardown(job);
  }
}

And then its a simple matter to configure Unity to wrap every job it creates with the EnsureJobExecutionExceptionDecorator. Not that hard is it?

And finally there is the code snippet that unfreezes my test thread when I’m done.

public class UnfreezeWhenJobShouldNotRunAgain : IRetryStrategy
{
  private readonly IRetryStrategy inner;
  private readonly ManualResetEvent reset;
  public UnfreezeWhenJobShouldNotRunAgain(
    IRetryStrategy inner,
    ManualResetEvent reset)
  {
    this.inner = inner;
    this.reset = reset;
  }
  public bool ShouldRetry(IJobExecutionContext context)
  {
    bool shouldRetry = this.inner.ShouldRetry(context);
    if (!shouldRetry)
    {
      this.reset.Set();
    }
    return shouldRetry;
  }
  public ITrigger GetTrigger(IJobExecutionContext context)
  {
    return this.inner.GetTrigger(context);
  }
}

Yet another decorator. Whenever the RetryJobListener from the first post of this series queries the IRetryStrategy wether a job should be run again the decorator checks for “yes” or “no”. And in case of a “no” it will set the ManualResetEvent and allow the test thread to continue.

So we have decorators, an abstract factory and dependency injection here. And all of that in less than 200 lines of code. All pieces short and to the point but by combining them you can build mighty powerful solutions that are still clean and easy to understand.

I hope you enjoyed the series and come back for another read. See you soon!

Testing Retries in Quartz.NET

This is the second in a series of posts.

In the last post I showed you the moving parts for persistent retries with Quartz.NET. Now it’s time to bring them all together.

With a little trick it is quite easy to run the actual Quartz.NET scheduler in a unit test. My current testing framework of choice is xUnit. So that’s what I will use in my code.

[Fact]
public void Should_Try_3_Times_And_Then_Give_Up()
{
  ISchedulerFactory factory = new StdSchedulerFactory();
  IScheduler scheduler = factory.GetScheduler();

  AlwaysFails alwaysFails = new AlwaysFails();
  IJob decoratedJob = new EnsureJobExecutionExceptionDecorator(alwaysFails);
  var jobFactory = new Mock<IJobFactory>();
  jobFactory
    .Setup(
      jf => jf.NewJob(It.IsAny<TriggerFiredBundle>(), It.IsAny<IScheduler>()))
    .Returns(decoratedJob);

  ManualResetEvent reset = new ManualResetEvent(false);
  IRetrySettings settings = new InMemoryRetrySettings
    {
      BackoffBaseInterval = 250.Milliseconds(),
      MaxRetries = 2
    };
  IRetryStrategy sut = new ExponentialBackoffRetryStrategy(settings);
  IRetryStrategy retryStrategy = new UnfreezeWhenJobShouldNotRunAgain(sut, reset);
  IJobListener retryListener = new RetryJobListener(retryStrategy);

  scheduler.ListenerManager.AddJobListener(
    retryListener,
    GroupMatcher<JobKey>.AnyGroup());
  scheduler.JobFactory = jobFactory.Object;

  ITrigger trigger = TriggerBuilder
    .Create()
    .StartNow()
    .WithSimpleSchedule(
      x =>
      {
        x.WithIntervalInSeconds(1);
        x.WithRepeatCount(0);
      })
    .WithIdentity("always", "fails")
    .Build();

  IJobDetail job = JobBuilder
    .Create<AlwaysFails>()
    .WithIdentity("always", "fails")
    .Build();

  scheduler.ScheduleJob(job, trigger);
  scheduler.Start();
  scheduler.ResumeAll();

  reset.WaitOne(15.Seconds());

  Assert.Equal(3, alwaysFails.Counter);
}

We start by setting up the SchedulerFactory and use it to get us a live Quartz.NET scheduler.

For this test I want to be able to tell that scheduler how it should create instances of my job class. I usually use a DI container to implement that factory but for the purpose of this test I use a mock object created with Moq.

Whenever the scheduler asks for an instance of the AlwaysFails job the factory returns a canned instance I created as part of my test setup. I explain the EnsureJobExecutionExceptionDecorator in another post.

Next I plug the actual RetryJobListener together and set it up to listen to all jobs using a catch-all matcher.

Then I configure my job to run immediately. Note that you can instruct the scheduler to run your job repeatedly but that is not what I want here. Under ideal circumstances the job should run once and be done with it. Only in case of failure do I want to run it again. And as another note: You can set a flag on the JobExecutionException that will cause the scheduler to retry immediately. But again: Not what I want.

When you start the scheduler it will create a background thread and do all its work there. The test method will just continue and exit before anything meaningful happens. Thus I need to freeze the test execution thread for a little while. This is what the ManualResetEvent is used for. To allow the test to continue as soon as the retry strategy says we are done trying I use another decorator. This one wraps the retry strategy. Please see the aforementioned post for further details.

In this test I use a large part of the Quartz.NET infrastructure. It’s not quite a system test but close enough for me at the moment. It can be run along with my unit tests because everything is done in-memory and it really doesn’t take that long to finish.

In the final post of this series we will make an excursion into the realm of composable software systems. Stay tuned!

Retries with Quartz.NET

This is the first in a series of posts.

Whenever you have a task that might take a while to complete it is usually a good idea to run it in the background and not block your application.

What makes up “a while” and how far “in the background” you should run your tasks is usually up for discussion.

The scenario here is an ASP.NET web application that needs to perform tasks and might fail because some objects that need to be modified are locked. If a task hits such a lock it should be run again later after waiting a little. And again after waiting some more. And again. And then again sometime in the middle of the night when it is rather improbable that the objects are still locked. And then give up eventually sending a notification to a human to resolve the problem.

For in process retries Microsoft p&p offers the Transient Fault Handling Application Block (infos on MSDN and CodePlex). But I needed a persistent retry strategy that would kick in if the application goes down for one reason or another.

There are a lot of things to keep in mind when running recurring tasks inside ASP.NET and a lot of really good reasons why you don’t want to write your own scheduler. Luckily there are quite a few alternatives to that.

I decided to solve my problem using Quartz.NET. It is free. It is battle hardened. It is widely used so the search engine of my choice will be able to find a substantial amount of blog posts and questions on popular Q&A sites. And last but not least: I wanted to take a look at it for quite some time.

I don’t want to give an introduction to Quartz.NET here. Their website does a fairly good job (no pun intended) at that.

So I will jump right into the thick of things and show you my approach to how to implement retries using Quartz.NET.

After some web search I decided to use this post as a starting point but make some adjustments along the way.

To implement custom tasks (or jobs as Quartz calls them) you have to implement the IJob interface. It doesn’t get any more straightforward. Implement your logic inside the single method of the interface and you are done. The only thing to keep in mind is that your job must only throw exceptions of a specific type. I outline my solution to that problem in another post of this series.

To be able to test my solution I created a job that would always fail. That turned out to be really simple.

public class AlwaysFails : IJob
{
  private int counter;
  public AlwaysFails()
  {
    this.counter = 0;
  }
  public int Counter
  {
    get { return this.counter; }
  }
  public void Execute(IJobExecutionContext context)
  {
    this.counter++;
    throw new NotImplementedException();
  }
}

For every call to the Execute()-method I increase a counter by one and throw an exception. Quartz requires that you only throw JobExecutionException inside your jobs. There is a simple solution to that problem that allows me to ignore this requirement here.

Now to the interesting part. As mentioned by the post linked above a custom IJobListener is the best place to put your retry logic. But I don’t want to hard-wire the logic that calculates whether the job should run again or when the next attempt should be made into the handler itself.

The listener only looks at whether the job failed. Then it asks a retry strategy (we will come to that in a moment) if the job should run again. And if the answer is yes it asks the strategy when the next attempt should be made and reschedules the job accordingly.

public class RetryJobListener : JobListenerSupport
{
  private readonly IRetryStrategy retryStrategy;
  public RetryJobListener(IRetryStrategy retryStrategy)
  {
    this.retryStrategy = retryStrategy;
  }
  public override string Name { get { return "Retry"; } }
  public override void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException)
  {
    if (JobFailed(jobException) && this.retryStrategy.ShouldRetry(context))
    {
      ITrigger trigger = this.retryStrategy.GetTrigger(context);
      bool unscheduled = context.Scheduler.UnscheduleJob(context.Trigger.Key);
      DateTimeOffset nextRunAt = context.Scheduler.ScheduleJob(context.JobDetail, trigger);
    }
  }
  public override void JobToBeExecuted(IJobExecutionContext context)
  {
  }
  private static bool JobFailed(JobExecutionException jobException)
  {
    return jobException != null;
  }
}

Nothing fancy so far. The retry strategy that contains the logic to determine whether or not the job should run again consists of the simple interface IRetryStrategy

public interface IRetryStrategy
{
  bool ShouldRetry(IJobExecutionContext context);
  ITrigger GetTrigger(IJobExecutionContext context);
}

and (as of now) one implementation for an exponential back-off strategy.

public class ExponentialBackoffRetryStrategy : IRetryStrategy
{
  private const string Retries = "Retries";
  private readonly IRetrySettings settings;
  public ExponentialBackoffRetryStrategy(IRetrySettings settings)
  {
    this.settings = settings;
  }
  public bool ShouldRetry(IJobExecutionContext context)
  {
    int retries = GetAlreadyPerformedRetries(context);
    return retries < this.settings.MaxRetries;
  }
  public ITrigger GetTrigger(IJobExecutionContext context)
  {
    int retries = GetAlreadyPerformedRetries(context);
    long factor = (long)Math.Pow(2, retries);
    TimeSpan backoff = new TimeSpan(this.settings.BackoffBaseInterval.Ticks * factor);

    ITrigger trigger = TriggerBuilder.Create()
      .StartAt(DateTimeOffset.UtcNow + backoff)
      .WithSimpleSchedule(x => x.WithRepeatCount(0))
      .WithIdentity(context.Trigger.Key)
      .ForJob(context.JobDetail)
      .Build();

    context.JobDetail.JobDataMap[Retries] = ++retries;
    return trigger;
  }
  private static int GetAlreadyPerformedRetries(IJobExecutionContext context)
  {
    int retries = 0;
    object o;
    if (context.JobDetail.JobDataMap.TryGetValue(Retries, out o) && o is int)
    {
      retries = (int)o;
    }
    return retries;
  }
}

Like in the example we use the JobDataMap of the job to store the retry counter. That map is automatically persisted (if you configured a persistent IJobStore) between runs so we won’t loose that counter. We can configure how many retries should be performed using the IRetrySettings. There is an in-memory implementation and one that hooks up with my playground’s configuration system. The details don’t matter here so I will just show you the interface declaration.

public interface IRetrySettings
{
  int MaxRetries { get; }
  TimeSpan BackoffBaseInterval { get; }
}

Until we hit the upper boundary of MaxRetries we calculate the time the job should wait and create a new trigger for the next run using Quartz’ fluent TriggerBuilder. Don’t forget to increase the counter for the retries!

Well and that’s the implementation part. The next post will show you how to bring it all together for a test run.

Quartz and other gems

Originally I intended to write a post about retries using the Quartz.NET scheduler.

But the post ended up being far too long so I decided to break it up into a short series.

  1. Retries with Quartz.NET
  2. Testing Retries with Quartz.NET
  3. Quartz.NET meets Design Patterns

Customer-extensible configuration

While playing around with custom resources I wondered what ways there are to configure which IResourceManager is used for those generated classes.

As I mentioned before I’m not particularly fond of XML for configuration purposes. But the *.config files are still the most commonly used means to configure a .NET application.

My goal was to allow a developer to configure which of a set of predefined resource managers to use (an obvious choice would be the file based approach with the .NET ResourceManager and maybe a database based implementation) while allowing him to add his own implementations later on. That kind of extensibility calls for an abstract factory approach.

The config file should look something like this

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="i18n" type="Playground.I18nSettingsSection, Playground" />
  </configSections>
  <connectionStrings>
    <clear />
    <add name="DEFAULT" connectionString="localhost"/>
  </connectionStrings>
  <i18n>
    <resxManager>
      <db connectionStringName="DEFAULT" />
    </resxManager>
  </i18n>
</configuration>

File 1: What I wanted my App.config to look like

The code behind that solution should be quite simple. Along the lines of:

public class I18nSection : ConfigurationSection
{
  [ConfigurationProperty("resxManager")]
  public ResourceManagerSettings ResourceManager
  {
    get { return (ResourceManagerSettings) base["resxManager"]; }

    set { base["resxManager"] = value; }
  }
}

public abstract class ResourceManagerSettings : ConfigurationElement
{
  public abstract IResourceManager GetResourceManager(Type resourceFileType);
}

File 2: What I thought might be a good idea for the code behind

When was anything ever that easy? The whole thing blew up in my face. The underlying problem being that the .NET configuration system cannot create an instance of an abstract class (the ResourceManagerSettings) and you can neither get access to the code where the instantiation happens (it’s a private method somewhere inside ConfigurationElement) nor can you handle it via overriding OnDeserializeUnrecognizedElement in your section class. The element is not truly unrecognized if you decorate the ResourceManager property with the ConfigurationPropertyAttribute so the method would never be triggered. You can remove the attribute but then where do you store the created object? You can’t call base["resxManager"] anymore because there is no longer a ConfigurationProperty with that name. And what if you had more than one “unrecognized element” in that section? You couldn’t assume that you where to create a concrete implementation of your abstract ResourceManagerSettings which would make figuring out which class to instantiate quite a bit harder (remember that you want the developer to be able to extend that solution later).

So I had to figure out another approach. What eventually worked was moving the whole concept up one level in the hierarchy of the config system. Where I formerly used a ConfigurationSection I had to use a ConfigurationSectionGroup as base class. And the ConfigurationElement became a ConfigurationSection.

What I ended up with was an App.config that looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="i18n" type="Playground.I18nSettingsSectionGroup, Playground">
      <!--<section name="file" type="Playground.FileResourceManagerSettings, Playground"/>-->
      <!--<section name="null" type="Playground.NullResourceManagerSettings, Playground"/>-->
      <section name="db" type="Playground.DbResourceManagerSettings, Playground"/>
    </sectionGroup>
  </configSections>
  <connectionStrings>
    <clear />
    <add name="DEFAULT" connectionString="localhost"/>
  </connectionStrings>
  <i18n>
    <db connectionStringName="DEFAULT" />
  </i18n>
</configuration>

File 3: Actual App.config

And the code behind to match the .config file:

public class I18nSettingsSectionGroup : ConfigurationSectionGroup
{
  public const string NAME = "i18n";

  private ResourceManagerSettings _ResourceManagerSettings;

  public ResourceManagerSettings ResourceManager
  {
    get
    {
      if (this._ResourceManagerSettings != null)
      {
        return this._ResourceManagerSettings;
      }

      if ((this._ResourceManagerSettings = this.Sections.OfType<ResourceManagerSettings>().SingleOrDefault()) == null)
      {
        this._ResourceManagerSettings = new FileResourceManagerSettings();
        this.Sections.Add(FileResourceManagerSettings.NAME, this._ResourceManagerSettings);
      }

      return this._ResourceManagerSettings;
    }

    set
    {
      ResourceManagerSettings resourceManagerSettings = this.Sections.OfType<ResourceManagerSettings>().SingleOrDefault();

      if (resourceManagerSettings != null && !Equals(resourceManagerSettings, value))
      {
        this.Sections.Remove(resourceManagerSettings.SectionInformation.SectionName);
      }

      this.Sections.Add(value.SectionInformation.Name, value);
    }
  }
}

public abstract class ResourceManagerSettings : ConfigurationSection
{
  public abstract IResourceManager GetResourceManager(Type resourceFileType);
}

public class FileResourceManagerSettings : ResourceManagerSettings
{
  public const string NAME = "file";

  public override IResourceManager GetResourceManager(Type resourceFileType)
  {
    return new ResourceManagerWrapper(new ResourceManager(resourceFileType.FullName, resourceFileType.Assembly));
  }
}

File 4: Actual implementation

In the <configSections> part of the .config file I configure the I18nSectionGroup with at most one (!) implementation of the ResourceManagerSettings. If you add multiple implementations the .NET configuration system will instantiate all of them when you read from the file. And now you would have to figure out which one you actually wanted to use. So (by design!) the code above will fail in case you configured more than one ResourceManagerSetting.

If you don’t configure anything the I18nSectionGroup will fall back to the FileResourceManagerSettings. I believe that’s an acceptable default.

When you set the I18nSectionGroup.ResourceManager property at run-time and save the configuration back to disk the correct section type will be persisted in the <configSections> part of your .config file.

So what I got is not exactly what I wanted. If the .NET framework weren’t as uptight about the object creation (the configuration system is by no means the only part of the framework that behaves like that!) the whole exercise would have been a lot easier. To MS’ defense: From the comments in the code of the ConfigurationElement they seemed to have some security considerations going on. Still, they might (at least) have provided a way to influence what type of object should be created if they couldn’t/didn’t want to let you handle the instantiation itself.

Anyway. You now have a means to configure where your resources are loaded from and if you want to add another source (like RavenDB for example) you can always do so with little effort. If you either mark your resource classes with an interface or a custom Attribute or decide on a naming convention it is really easy to brew up a little reflection code that sets the static ResourceManager property at application start-up.

Item templates and custom resources

In a previous post I wrote about Custom resources with T4 templates. Back then I used the ReSharper multi-file templates to add the .resx and .tt files to my projects. The one downside of that approach: it requires R# 8.x which might not be readily available.

Thus I wanted to find out how to create a Visual Studio item template that achieves the same goal. Microsoft has a step-by-step guide that explains the process. That gives you the basics. But there is some fine-tuning that they don’t explain.

If you add a .resx file to your project the generated .Designer.cs file is hidden in the solution explorer. I wanted to do the same and hide the .tt file underneath the .resx file. Preferably I wanted both the .tt and the generated .Designer.cs file on the level directly below the .resx file (as shown in the first screenshot). But the TextTemplatingFileGenerator always puts the generated output file on the level below the .tt file (as in the second screenshot) on every run. I decided to stop battling VS. Its not worth the effort in this case.

Screenshot 1: Nice to have

Screenshot 1: Nice to have

Screenshot 2: What you actually get

Screenshot 2: What you actually get

To actually hide the .tt file via the item template is quite easy if not really prominently advertised. There’s a post on stackoverflow that explains how you need to modify your template.

The second <ProjectItem> is the interesting part. You need to prefix the .tt file with the path to the .resx file. When the item template is invoked that will translate to a <DependentUpon> clause in your project file.

<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
  <TemplateData>
    <DefaultName>Resource.resx</DefaultName>
    <Name>Customizable resources</Name>
    <Description>Creates a .resx file that uses a T4 template to generate strongly typed resources.</Description>
    <ProjectType>CSharp</ProjectType>
    <SortOrder>10</SortOrder>
    <Icon>__TemplateIcon.ico</Icon>
  </TemplateData>
  <TemplateContent>
    <References>
      <Reference>
        <Assembly>System</Assembly>
      </Reference>
      <Reference>
        <Assembly>mscorlib</Assembly>
      </Reference>
    </References>
    <ProjectItem SubType="" TargetFileName="$fileinputname$.resx" ReplaceParameters="true">Resource.resx</ProjectItem>
    <ProjectItem SubType="" TargetFileName="$fileinputname$.resx\$fileinputname$.tt" ReplaceParameters="true">Resource.tt</ProjectItem>
  </TemplateContent>
</VSTemplate>

File 1: MyTemplate.vstemplate

Also make sure that you set ReplaceParameters="true" for the .resx file. You will want to add template parameters for the namespace and the class name.

For that I used two of the predefined parameters: $rootnamespace$ and $safeitemname$. Note that the first one gives you the full path to your .resx file and not the root namespace of the current project! If you place the resources in project Foo in the folder Assets the value of $rootnamespace$ will thus be Foo.Assets. Maybe someone at MS thought that’s a funny way to lead developers on a wild goose chase …

And that’s what the .tt file looks like

//------------------------------------------------------------------------------
// <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="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Xml.Linq" #>

namespace $rootnamespace$
{
    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.Resources;
    using System.Threading;
    using MyI18n;

    public class $safeitemname$
    {
        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("$rootnamespace$.$safeitemname$", typeof($safeitemname$).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 $safeitemname$.ResourceManager.GetString(\"" + name + "\", resourceCulture ?? CultureInfo.CurrentUICulture); }");
            WriteLine("        }");
        }
    }
#>
    }
}

File 2: Resource.tt

Don’t forget to adjust your using statements to the location of the IResourceManager interface and the ResourceManagerWrapper class.

Your .zip file should look something like this:

Screenshot 3: Contents of the .zip file

Screenshot 3: Contents of the .zip file

 

Now copy it to "C:\Users\[YOUR USERNAME]\Documents\Visual Studio [YOUR VISUAL STUDIO VERSION]\Templates\ItemTemplates\Visual C#" and fire up VS. Once you click “Add new item” your new template should appear right on top of the “Visual C# Items”.

Screenshot 4: Add new item

Screenshot 4: Add new item

 

You can download the template from my pet project’s site.