I’ve been talking about managing dependencies and unit testing in Azure Functions quite a few times in those articles:
- Is Your Serverless Application Testable? – Azure Functions
- Precompiled Azure Functions Revisited
- Testing Precompiled Azure Functions
- Debugging Azure Functions in Our Local Box
- Managing Dependencies in Azure Functions
- Testing Azure Functions in Emulated Environment with ScriptCs
Throughout my articles, the service locator pattern always took the centre of dependency management. The combination of Common Service Locator and Autofac certainly convinced me this would be the only way to handle dependencies for Azure Functions.
A few weeks back, I was asked to take a coding test before being engaged with a client. The topic was simple – given a JSON payload as a source of truth, I need to build an application to process the payload to display an instructed result. I, of course, decided to use Azure Functions to fulfill their requirements. Because the test itself was pretty straight forward, it could be done within a couple of hours with full of spaghetti code. However, they also wanted a sort of over-engineering including dependency injections, SOLID principles, unit testing, etc.
So, I started writing an Azure Functions application for it. As soon as I started, I realised that:
“Why can’t I upgrade my Autofac version? Is it because of the common service locator locks-in the Autofac version?”
This means that Azure Functions doesn’t yet support assembly binding redirects out-of-the-box. Apparently, it’s possible for libraries used internally. However, this is not applied to my case, if my Azure Functions app has dependencies that need binding redirects. Even though, there is an workaround for this concern, I was reluctant using this approach for Autofac.
What if I can use Autofac directly, without relying on Common Service Locator? Can I do this? It would be worth trying, yeah? Let’s move on.
Here’s my coding test repository as an example.
In my previous post, I introduced
ServiceLocatorBuilder for Autofac integration like:
This was called within
It seemed to be redundant. I wasn’t happy about that, but justified myself this would be the only way to do it. Now this is the time to rewrite. Let’s do it.
In the constructor of the new
FunctionFactory class, instantiate the
Autofac.IContainer instance directly from
Autofac.ContainerBuilder.ContainerBuilder instance. Then, within the
Create<TFunction>() method, the given type of function instance is resolved directly from the
Autofac.IContainer instance. Here’s the code.
The basic usage is the same as the previous version of
FunctionFactory. Simply create an instance and use it within the function method.
With this approach, you don’t need to use service locator pattern any longer for your dependency management. Hope this helps.