Azure WebJobs is a great way to run asynchronous, long-running or periodic jobs alongside an Azure website. Since version 1.0.1 the WebJobs SDK supports instance methods to be scheduled or triggered instead of only static methods. So before 1.0.1 we could have a trigger method signature:

public class Functions
{
  public static void ProcessQueue([QueueTrigger("input")] string input) { ... }
}

And now the following signature is allowed:

public class Functions
{
  public void ProcessQueue([QueueTrigger("input")] string input) { ... }
}

A small difference so what does that give us? Well, when only static methods are allowed, dependency injection becomes a problem. Dependencies can only be injected into instances of classes and static methods can not access instance fields/properties.

Instance methods can access instance fields so in theory, starting with WebJobs SDK 1.0.1 we could inject dependencies into the class containing our WebJob trigger method. I’m using SimpleInjector as my dependency injection framework of choice so I thought I’d try and figure out how to use SimpleInjector to inject dependencies into my WebJob.

This is actually quite simple as you would expect with SimpleInjector 🙂 First create an implementation of IJobActivator that accepts a SimpleInjector container:

using Microsoft.Azure.WebJobs.Host;
using SimpleInjector;
public class MyJobActivator : IJobActivator
{
  private Container container;

  public MyJobActivator(Container container)
  {
    this.container = container;
  }

  public T CreateInstance()
  {
    return (T) container.GetInstance(typeof(T));
  }
}

Next step is to configure the JobHost to use our job activator. Note I also configure the SimpleInjector container.

// Configure SimpleInjector.
var container = new Container();
container.RegisterSingle<IDependency, Dependency>();

// Configure JobHost.
var jobHostConfiguration = new JobHostConfiguration
{
  JobActivator = new MyJobActivator(container)
};
var jobHost = new JobHost(jobHostConfiguration);

The class that has our WebJobs trigger method has the following signature:

public class Functions
{
  private IDependency dependency;

  // Constructor injection of IDependency.
  public Functions(IDependency dependency)
  {
    this.dependency = dependency;
  }

  public Task ProcessQueueAsync([QueueTrigger("input")] string input)
  {
    // Use dependency to handle queue message.
    await dependency.HandleInputAsync(input);
  }
}

You can call the JobHost start methods just as you did before. So for triggered jobs you use RunAndBlock, for scheduled jobs use one of the Call or CallAsync methods.

Ronald Wildenberg

Author Ronald Wildenberg

Coming from an Artificial Intelligence background, turned developer after graduating. Interested in the tiny programming language details that make your life simpler but also in high-level designs that solve business problems in the most efficient way. And everything in between of course.

More posts by Ronald Wildenberg
3 July 2015

Join the discussion 2 Comments

Leave a Reply