In my quest to find the "right way of doing things", or failing that "the least worst way of doing things" - I've come across a fairly well hidden secret about using Dependency Injection in Azure WebJobs.
The full source code can be found in GitHub
In this post I'm assuming you already know how to set up a WebJob (if not check out this article) - yes it is a bit long, but it's comprehensive and will give you great insight into the WebJobs SDK.
Once, you're all setup we can start adding Dependency Injection to our WebJob.
In our WebJob we'll likely have a Functions.cs class - in this we'll have a method which will run - given a trigger; be it a Queue, BlobInput/BlobOutput or a Schedule.
Here's the default Functions.cs after creating a WebJob through the Visual Studio WebJob template
Notice the static method and lack of default constructor created for us?? Well we're going to change that and use Constructor Injection.
First, we need to get our IOC (Inversion of Control) Container (I've been using Autofac a lot recently, I like the features and the style, so I'll be using that). I've grabbed it from NuGet.
Great, so the next step is to tell our WebJob Host how to resolve dependencies - as it's not familiar with Autofac - we need to implement a very simple interface, which allows us to resolve the dependencies when asked.
I've created a class called AutofacActivator which implements IJobActivator
It accepts an IContainer (Autofac specific) in it's constructor (we're going to manually pass this in).
Now we have to tell the Job Host about our Activator, this is done in Program.cs in the main method. You'll notice that this looks a lot like a .Net Console Application - that is no coincidence!!! You can take a standard console app and deploy it as a WebJob.
The Main method in the WebJob (just like a Console App) is the entry point into the Application.
In here we pass our created container - it's specific to Autofac, you can see how it's done in the source, however its not really essential from the perspective of this post. A container in Autofac is just somewhere your components are managed.
IMPORTANT - Make sure you register the Functions class with your container - the WebJob host will get your Methods with Triggers through the container too. In Autofac it looks like this:
var builder = new ContainerBuilder(); builder.RegisterType<Functions>();
Finally, we go back to change our Functions.cs to be "injectable".
Notice we've removed all "static"'s from the file, added a parameter to our constructor and I've included a simple
log.WriteLine to show the usage of the dependency.
Hopefully this has given a good insight into Azure WebJobs and Dependency Injection. I'm surprised there isn't any official Microsoft Documentation on this subject, and the main resources for people are StackOverflow answers.
Anyway, hope you've learnt something from reading, hit me up on Twitter if you have any comments!