This blog focuses on implementing the Dependency Injection design pattern to the Azure Functions. For a better understanding of Dependency Injection and Azure Function, Let’s take a simple Cab booking validation scenario, in which there will be a Function app implemented with the Dependency Injection that validates the user email Id that is valid or not.
Before diving into the orchestration, let us know what the Dependency Injection is.
What is Dependency Injection?
Dependency Injection is a design pattern used to create loosely coupled modules of code. With Dependency Injection, Code maintenance will be improved, and Scaling will be smooth. It helps the user to achieve the Inversion of Control (IoC) between classes and their dependencies.
Consider a scenario where there is a single service that needs to be accessed by many modules.
The Traditional Way of Coding
In the traditional way, each module will create an object of the Service to access its properties and methods. This gets the module and the service tightly coupled, the impact being more memory consumption and low efficiency due to more objects.
With dependency injection, a single object will be created with the builder object that can be accessed by all the modules. Here a module can access the object of the service created by injecting the dependency to the builder object. This shows that the modules and the service are loosely coupled due to the centralized builder object.
Why Should I Use Dependency Injection?
Using Dependency Injection has a lot of benefits than the traditional way of coding. Below are some of the key advantages of using Dependency Injection in the project:
- Loosely coupled: Being loosely coupled, Updating the code will be easier. A single change in the service object will be reflected in all other modules or dependent services.
- Reusable: When there are multiple modules in a project, a single independent service can be reused in any of the modules if it is implemented with the Dependency Injection
- Readable Code: Dependency Injection makes the code readable as it moves all the dependencies to the builder object. This makes it easier to investigate the dependencies of a module from a single file.
- Lifetime: There are various service lifetimes available with which the builder object assigns the lifetime to the service object. The lifetime can be given at the request level, executive level, and project level.
As of now, we got a clear picture of what is Dependency Injection and its benefits. Now we will see how to implement Dependency Injection into Azure Functions with a real-world scenario.
What is Azure Function?
Azure Function App is a serverless compute service that enables the user to run event-triggered code without having to provision or manage infrastructure. Being a trigger-based service, it runs a script or piece of code in response to a variety of events. This Azure Function can be created either from the Azure portal or using Visual Studio.
Below is the good read on Azure Function and its components:
Dependency Injection in Azure Functions
To get the understanding of the implementation of Dependency Injection in the Azure Functions, let’s take a simple booking validation scenario that was mentioned in the Introduction.
In this orchestration, there is an Azure Function that will validate the User email Id. In that Function, there will be a validator service that validates the user email Id and tells whether the user is valid or not.
To make the connection between the Azure Function and Validator Service, a Dependency Injection design pattern has been used. Below is the Procedure to implement the Dependency Injection into the Azure Functions.
Dependency Injection in Azure Functions cannot be implemented from the Azure Portal. Dealing with objects, dependency needs to be implemented within the class whereas, in the Azure portal, there will be a static Function without a class. So, there will be a need for a Visual Studio tool for Dependency Injection implementation.
Create a New Project
First, we need to create an Azure Function Project. In our scenario, the project name is UserDetailsValidator.
After creating the project, we need to create a validator service interface and a class to use it in the validator functions. Below are the code implementations of IValidatorService and ValidatorServic:
Now we should create a Startup assembly file that will instantiate the builder object to register the Service object with Service Interface. IFunctionsHostBuilder can be used as a builder to map ValdiatorService and IValidatorService. Below are the prerequisites that need to be installed to make the C# file into an assembly file.
- Azure.Functions.Extensions – 1.0.0
- Extensions.Http – 2.2.0 (Do not install the Latest version, Azure Functions is not upgraded yet to support its latest version)
- Microsoft.NET.Sdk.Functions package version 1.0.28 or late
After Installing the above mentioned NuGet Packages, create a Startup class that should inherit the FunctionStartup. It will prompt you to add the override Configure Function.
This Startup class is where the Dependency Injection will be implemented. Here we can also add our own logging service that might be used throughout the application.
In the above code, we have used Singleton Service Lifetime. This will Instantiate the ValidatorService for a single time and it can be accessed by any object that injects the IValidatorService in its Constructor.
The Service and Startup assembly are implemented. Now we need to code the Azure Function to access the ValidatorService. Below is the implementation of Azure Function:
In the above code, we have defined the IValidatorService Interface in the Constructor that will instantiate the ValidatorService in the runtime.
After passing the email Id to the EmailValidator Function of the ValidatorService, the function will validate and return the Response as “Valid” or “Invalid”.
Now the Azure Function is set up and It needs to be published to the portal to run in the cloud. Publishing the Azure Function from visual studio to Azure Cloud is simple and straight forward that can be done in a matter of seconds.
To Publish the Azure Functions
- Right-click on the project and select Publish to publish the project
- Give the details like Subscription name, Resource group, and Functions name and Click Create
- It will create a profile and the functions will be published
The above implementation of Dependency Injection works based on the Singleton Service Lifetime where the Service object is instantiated once, and it can be accessed by any objects at any time. However, there are some other Service Lifetimes with which the object instantiation can be restricted as required. Now Let’s see the different types of Service Lifetimes in the upcoming topic.
There are various Service lifetimes available in the Dependency Injection for Azure Functions that are detailed below:
Transient: In the transient lifetime, the Service object is created upon each request of the Service. Whenever there is a request for the service, it will create a new Object
Scoped: The scoped Lifetime is based on the execution of the Service. It will create an object whenever the service is called, and that object can be reused when the service gets called again
Singleton: For Singleton, the service object is created only once, and it can be used across the functions in an instance. Singleton is mainly recommended to use for Database context objects, HTTP Client, SQL Connections, etc.,
In this blog, we saw what Dependency Injection is? implementing it into Azure Functions and more. The above-mentioned method of implementing Dependency Injection into Azure Functions is the same as implementing it into ASP.NET Core. And the Dependency Injection can also be implemented using other 3rd Party services like Autofac, etc.,
Check out our community initiative, ServerlessNotes, to know more about Azure Functions and best practices. Happy Coding!!!