When starting to play around with Azure Functions, the lack of dependency injection support was pretty annoying. To overcome that issue I created a small library, Autofac On Functions, based on Azure Functions 1.x. Unfortunately it is not possible to generate a nuget package from these sources.
Azure On Function with nuget package available
Yesterday I started to play around with Azure Functions v2. It is available as beta version supporting dotnet standard and .net core. Updating was pretty relaxed beside the fact, that there had been some incompatible changes.
The good news is, packaging assemblies with reference to the Azure Functions SDK is now possible. So here it is:
This is a quite early state, but it is fully functional and provides exactly the functionality that is necessary. You can also download the sources on github.
What you need to get it running
What do you need to enjoy Azure Functions with dependency injection?
You can just download the sample also from Github here. Nuget package 0.1.5 is referenced. Make sure, you have the latest Azure Functions that supports .net standard on your machine.
Create an Azure Functions project
Simple open Visual Studio, and create a new project. Select “Azure Functions”.
Select type of Azure Function
Azure Functions v2 offers a little more infrastructure, also the dialog to add Azure Functions looks a little different. I didn’t select a storage account as for the sample it is simply not necessary. An http trigger function is going to be created on base of .net standard.
Add dependency to AutofacOnFunctions
Right click your project and select “manage nuget packages”. Search for AutofacOnFunctions under “browse”. Install current version. Again, be aware that it “only” supports .net standard.
Add a test service
With above steps, Visual Studio created an Azure Function. Nuget package is there. What do I need to do to use Dependency Injection now?
Create a simple service to be injected into your http triggered Azure Function and the interface:
Add a Bootstrapper
The bootstrapper will tell the framework which modules need to be loaded, thus which services shall be registered.
Certainly, the “ServiceModule” contains your newly created test service:
Inject your service in Azure Functions
Use the InjectAttribute to let your service being injected by Autofac.
See the Results
Just hit f5 and let’s see the results.
Custom provider for the InjectAttribute had been loaded. The provider will only be loaded, when there is at least one Inject attribute used. If an inject attribute is used, but there is no bootstrapper available, the framework will raise an exception as the Azure Function will not be able to start.
When you copy the marked url above and paste it in the browser of your choice, you should see this result:
Finally find all sources in this repository. Enjoy!
I had an very interesting chat about property vs method injection within Azure Functions with Justin Yoo. You can follow the chat in his latest post Dependency Injection on Azure Functions. The actual question is: Does it make sense due to the static nature of Azure Functions to use method injection? Constructor injection certainly is not sensibly possible, would property injection be the better choice?
Actually I do like Justin’s approach with the FunctionFactory. To keep changes on method signatures low and therefore keep the effort in maintaining unit tests low, I would prefer to just inject the FunctionFactory instead of having a different approach.
I am going to set up a sample and let you guys know.
- As promised I did setup a sample for the FunctionFactory approach. Actually I didn’t upload it anywhere as from my perspective this approach is not benefitial:
The function itself doesn’t define the dependencies anymore. Using the factory hides this important information
- There is actually no need for an infrastructural solution with a static “FunctionFactory” from my point of view. If the function shall consume a Factory, the InjectAttribute can be used for doing so. Just using depedency injection to access services does not undercut the overall architecture which should be primarly dependency injection usage with in best case no exception.
- I do not like the fact, that the function itself follows a certain pattern to increase testability. A public static property that is used to change the behavior of the function is from my point of view not preferrable.
Just a sample to explain the approach. This is the code from Justin
When set up like this, testing is quite straight. The only drawback is, that it is not possible to set up different container per function.