Native Dependency Injection in Azure Functions with C#
Tags: csharp, azure, serverless, architecture
Published: 2020-10-01 19:03:42

C# Azure Functions support dependency injection through the native container.

This allows us to use the Dependency Inject principle in native Azure Functions. In this post, we're going to create a simple function to demonstrate the use of it.

Also, check out my blog with other articles --> https://rmauro.dev

### Introduction
> Azure Functions allows you to run small pieces of code (called "functions") without worrying about application infrastructure. With Azure Functions, the cloud infrastructure provides all the up-to-date servers you need to keep your application running at scale.
https://docs.microsoft.com/en-us/azure/azure-functions/functions-overview

For this demonstration, we're going to use this **RandomNumberService** to Inject into our function.

```csharp
using System;

namespace DependFunction.Services
{
    public interface IRandomNumber
    {
        int GetRandom();
    }

    public class RandomNumberService : IRandomNumber
    {
        static readonly Random _rand = new Random();

		//Get's a random number
        public int GetRandom() => _rand.Next(0, 10);
    }
}
```

### Required Dependencies
Install/Update the following *NuGet* packages in your project.

- Microsoft.Azure.Functions.Extensions
- Microsoft.NET.Sdk.Functions

```xml
<Project Sdk="Microsoft.NET.Sdk">
  <!--ommited code-->
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.9" />
  </ItemGroup>
    <!--ommited code-->
</Project>
```

### Registering the Services in the Container
To register the services and we need to create a *startup function*, just like we have in a common asp.net core application.

Create a file called `FunctionStartup.cs` at the root of your application.

![Solution Explorer](https://res-4.cloudinary.com/ht54oxr6q/image/upload/q_auto/v1/ghost-blog-images/func-solution-2.png)

Paste the following content into the file.

```csharp
using DependFunction.Services;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(DependFunction.Startup))]
namespace DependFunction
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton<IRandomNumber, NumberService>();
        }
    }
}
```

#### Explanation

Before the namespace we're registering our class as a dependency start the function `[assembly: FunctionsStartup(typeof(DependFunction.Startup))]`. This will tell the function runtime to trigger our class before serving HTTP requests.
*Do not use to process other things, only to register services.*

Inheriting `FunctionStartup` we gain access to `IFunctionsHostBuilder` object where we can register all dependencies, such as Scoped, Transient, or Singleton.

#### Service Lifetime
- Transient: Transient services are created upon each request of the service.
- Scoped: The scoped service lifetime matches a function execution lifetime. Scoped services are created once per execution.
- Singleton: The singleton service lifetime matches the host lifetime and is reused across function executions on that instance.

### Using the service though Dependency Injection
Open your function file do the following changes
- Remove `static` marker from the class and the function (we need to inject using constructors)
- Create a constructor and inject the dependency interface

You should end with something like this:

```csharp
using System;
using System.Threading.Tasks;
using DependFunction.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace DependFunction
{
    public class Function1
    {
        private readonly IRandomNumber _randomService;

        public Function1(IRandomNumber randomService)
        {
            _randomService = randomService ?? throw new ArgumentNullException(nameof(randomService));
        }

        [FunctionName("Function1")]
        public IActionResult Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");
            
            var result = new { random = _randomService.GetRandom() };

            return new OkObjectResult(result);
        }
    }
}
```

### Testing
Run the application and access the *URL* for testing.

![test-result](https://res-3.cloudinary.com/ht54oxr6q/image/upload/q_auto/v1/ghost-blog-images/func-result.png)

### Source Code

https://github.com/ricardodemauro/az-functions-article

Hope you like it. Leave a comment.

Also, check out my blog with other articles --> https://rmauro.dev