.NET Core  

How to Use Dependency Injection in .NET Azure Functions

Without Dependency Injection (DI), you would create these objects manually in every function. That quickly becomes messy.

Dependency Injection solves this by:

  • creating and managing these services for you,

  • giving them to your function automatically,

  • making your code easier to test and maintain.

1. Two ways of running Azure Functions

It’s important to know there are two models for .NET Azure Functions:

  1. In-process model (old way)

    • Functions run inside the same process as the Azure Functions runtime.

    • Uses a Startup class for DI.

    • Still supported, but will retire in 2026.

  2. Isolated worker model (new way, recommended)

    • Functions run in their own process.

    • Uses normal .NET Host and Program.cs for DI (just like ASP.NET Core).

    • More flexible and future-proof.

2. Setting up Dependency Injection in the In-Process Model

Step 1. Add required NuGet packages

dotnet add package Microsoft.Azure.Functions.Extensions
dotnet add package Microsoft.NET.Sdk.Functions

Step 2. Create a Startup class

This tells Azure Functions how to register your services:

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(MyApp.Startup))]

namespace MyApp
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            // Register HttpClient (best practice)
            builder.Services.AddHttpClient();

            // Register custom service
            builder.Services.AddSingleton<IMyService, MyService>();

            // Bind configuration section to options
            builder.Services.AddOptions<MyOptions>()
                .Configure<IConfiguration>((opts, config) =>
                {
                    config.GetSection("MyOptions").Bind(opts);
                });
        }
    }
}

Note

  • Singleton = one instance for the whole app

  • Scoped = one instance per function execution

  • Transient = new instance every time it’s requested

Step 3. Inject your service into a Function

public class MyHttpTrigger
{
    private readonly IMyService _myService;

    public MyHttpTrigger(IMyService myService)
    {
        _myService = myService;
    }

    [FunctionName("MyHttpTrigger")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req,
        ILogger log)
    {
        var result = await _myService.GetDataAsync();
        return new OkObjectResult(result);
    }
}

3. Setting up Dependency Injection in the Isolated Worker Model (Recommended)

Step 1. Create a new project (isolated worker)

func init MyIsolatedFuncApp --worker-runtime dotnet-isolated

Step 2. Add packages

dotnet add package Microsoft.Azure.Functions.Worker
dotnet add package Microsoft.Azure.Functions.Worker.Sdk

Step 3. Register services in Program.cs

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.DependencyInjection;

var builder = FunctionsApplication.CreateBuilder(args);

// Register custom service
builder.Services.AddSingleton<IMyService, MyService>();

// Register HttpClient
builder.Services.AddHttpClient();

// Register EF Core DbContext factory (optional)
builder.Services.AddDbContextFactory<MyDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// Register options from settings
builder.Services.Configure<MyOptions>(builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();
app.Run();

Step 4. Use the service in a function

public class MyHttpFunction
{
    private readonly IMyService _myService;

    public MyHttpFunction(IMyService myService)
    {
        _myService = myService;
    }

    [Function("MyHttpFunction")]
    public async Task<HttpResponseData> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req)
    {
        var result = await _myService.GetDataAsync();

        var response = req.CreateResponse(HttpStatusCode.OK);
        await response.WriteStringAsync(result);

        return response;
    }
}

Conclusion

Dependency Injection makes Azure Functions cleaner, testable, and future-ready. Use the in-process model only if you must, but for all new apps, prefer the isolated worker model to get the full benefits of modern .NET and long-term support. Keep functions lean—let DI handle your services.