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

Dependency Injection solves this by:

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

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.