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.
ServiceLocatorBuilder
No More In my previous post, I introduced ServiceLocatorBuilder
for Autofac integration like:
https://gist.github.com/justinyoo/ad11d9188b8ddc467d50b4efa2458b48
This was called within FunctionFactory
like:
https://gist.github.com/justinyoo/fd22aac8bb6c477f25314194e65bd741
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.
FunctionFactory
New 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.
https://gist.github.com/justinyoo/7c94feb6d258c451130afaec2fd3ebee
FunctionFactory
HttpTrigger with The basic usage is the same as the previous version of FunctionFactory
. Simply create an instance and use it within the function method.
https://gist.github.com/justinyoo/5990c22a51a958d6fd3d420952f5aea8
With this approach, you don't need to use service locator pattern any longer for your dependency management. Hope this helps.