Using AutoFac in Azure Functions

Let’s be blunt. If you’re new to Azure Functions, use Version 2. If you have existing Azure Functions, upgrade them. The use case for keeping version 1 is small and Azure is a consistently moving eco-system that punishes though that fall behind. The main obstacles for those upgrading are some changes to the triggers and the fact that triggers other than HTTP require them to be registered (so small code changes).

The main attraction for me is that Azure Functions Version 2 support Dependency Injection, so let’s jump straight in.

Why use AutoFac?

I won’t talk about the benefits of Dependency Injection or Inversion of Control because I’m sure if you’ve found an article about using Autofac in an Azure Function you are already familiar with them. Autofac is a great choice because of how easy it is to set up, which is what we will go through here.

Setting up the Azure Function

As always, you’ll need Visual Studio. I’m using 2017 community edition on a Windows so if you’re using VSCode or VS for Mac expect things to work but be ready to adapt the instructions.

Start a new project and select the template as ‘Azure Function’. From here select Anonymous Authentication and Storage Emulator from the options and wait a few seconds for the files to generate. You’re basically doing the same as my initial demo for Azure Functions so if you want some help with the first steps, check it out. Otherwise, let’s crack on!

Installing Autofac

Starting with Autofac is super easy. Open the package manager console (Tools > Nuget Packet Manager > Packet Manager Console) and run the command below. This is current as of 30/01/2018 but check the documentation first to ensure there isn’t a more recent version. If you get a Newtonsoft conflict or find it missing, install it manually first and then re-run the command below.

Install-Package AzureFunctions.Autofac -Version 3.0.6

Setting up Autofac

To use Autofac, we have to add a config class to be able to register the dependencies like we would in an old school Autofac instance.

Add a new class and add the code below. Note the two using statements to access the Autofac functionality. Here we are simply passing in a string ‘functionName’ and then initializing our registrations.

using Autofac;
using AzureFunctions.Autofac.Configuration;

namespace FunctionAppFAC
{
    public class DependencyInjectionConfig
    {
        public DependencyInjectionConfig(string functionName)
        {
            DependencyInjection.Initialize(builder =>
            {
                    //Implicity registration
                    builder.RegisterType<ExampleResponse>().As<IExampleResponse>();
                    //Explicit registration
                    //builder.Register<Example>(c => new Example(c.Resolve<ISample>())).As<IExample>();
                    //Registration by autofac module
                    // builder.RegisterModule(new TestModule());
                    //Named Instances are supported
                    // builder.RegisterType<Thing1>().Named<IThing>("OptionA");
            }, functionName);
        }
    }
}

Now that we have registered the dependencies, we need to add the dependency. Start by adding a new class called IExampleResponse with the code as follows.

namespace FunctionAppFAC
{
    public interface IExampleResponse
    {
        string Response(string name);
    }
}

Then add another class called ExampleResponse and add the following code.

namespace FunctionAppFAC
{
    public class ExampleResponse : IExampleResponse
    {
        public string Response(string name)
        {
           return $"The date is {System.DateTime.Now}";
        }
    }
}

You can see here that we aren’t doing anything complicated at all. We define our interface and the implementation which return the same functionality as the code but takes the control away from the function and into this implementation instead. We have already registered the dependency so that’s dandy.

Now we need to add it to our function. Go back to your ‘Function1’ class that Visual Studio generated for you when you created the project and annotate it with the following.

using AzureFunctions.Autofac;

namespace FunctionAppFAC
{
[DependencyInjectionConfig(typeof(DependencyInjectionConfig))]
    public static class Function1
    {
        public static IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]HttpRequest req, TraceWriter log, [Inject]IExampleResponse response)
{
            return new OkObjectResult(response);
}
    }
}

The important take away here is that after the TraceWriter, we have added our [Inject]IExampleResponse. That’s it! Autofac does the hooking up for us. Neat huh?

Testing the Implementation

So before anyone gets carried away, testing means hitting this function from a browser to make sure it works. I know the huge benefit of Dependency Injection is Mockable Unit Testing, but we will come to that next I promise!

So, hit F5 to run your function and wait for the familiar black console to tell you its ready. Use the URL in the console and paste it into the browser with “?name=David” appended at the end (for me this was http://localhost:7071/api/Function1?name=David) and see the response. Voila!

Summary

So yes, this walkthrough got you to exactly the same place as you’d have gotten with the default implementation. Only now, you have all the benefits of the Dependency Injection. Just imagine if that name you passed in hit a dependency that looked up that person and returned a full a profile for them? It could do, all by changing the dependency, not the actual core code. Nice. I will do some work on unit testing in Azure Functions next so watch out for that!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s