How to inject dependencies inside an ASP.NET Core Health Check

Short Answer

How to inject dependencies inside an ASP.NET Core Health Check.

If we register our services in a correct order, then SomeDependency will be available for injection into the SomeHealthCheck constructor, and SomeHealthCheck will run as part of the health check feature.

public void ConfigureServices(IServiceCollection services)
{
    services.AddHealthChecks();
    services.AddSingleton<SomeDependency>();

    // register the custom health check 
    // after AddHealthChecks and after SomeDependency 
    services.AddSingleton<IHealthCheck, SomeHealthCheck>();
}

More Details

A comment in the Health Check samples states that:

All IHealthCheck services will be available to the health check service and middleware. We recommend registering all health checks as Singleton services.

Full Sample

using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;

public class SomeDependency
{
    public string GetMessage() => "Hello from SomeDependency";
}

public class SomeHealthCheck : IHealthCheck
{
    public string Name => nameof(SomeHealthCheck);

    private readonly SomeDependency someDependency;

    public SomeHealthCheck(SomeDependency someDependency)
    {
        this.someDependency = someDependency;
    }

    public Task<HealthCheckResult> CheckHealthAsync(
        CancellationToken cancellationToken = default(CancellationToken))
    {
        var message = this.someDependency.GetMessage();
        var result = new HealthCheckResult(HealthCheckStatus.Failed, null, null, null);
        return Task.FromResult(result);
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHealthChecks();
        services.AddSingleton<SomeDependency>();
        services.AddSingleton<IHealthCheck, SomeHealthCheck>();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseHealthChecks("/healthz");
        app.Run(async (context) => await context.Response.WriteAsync("Hello World!"));
    }
}

This sample is also available on GitHub here.


As of .NET Core 3.0, the registration is simpler and boils down to this

public void ConfigureServices(IServiceCollection services)
{
    services.AddHealthChecks();
    services.AddSingleton<SomeDependency>();
    services.AddCheck<SomeHealthCheck>("mycheck");
}

Note that you no longer have the singleton vs transient conflict as you use what the engine needs to use.

The name of the check is mandatory, therefore you have to pick up one.

While the accepted asnwer seems no longer to work.


Dependency injection for health checks in asp.net core works exactly as it works for any other registered service that is added through ServiceProvider.

This means creating your health check as

public class Foo : IHealthCheck {
    private ILogger<Foo> _log;
    public Foo(ILogger<Foo> log) {
        _log = log; // log is injected through the DI mechanisms
    }
}

And registering (using the new 6 style here):

builder.AddHealthChecks().AddHealthCheck<Foo>();

So this also means that you can inject the IServiceProvider itself and utilise it internally should the need for getting further required services or werid use cases be there.

I am very curious why this is not explicitly stated in the documentation and there are no examples for this, as it is not "obvious". But it clearly follows the classical pattern of everything in the asp.net core land.


In addition to Shaun's answer: there is an open pull-request which will allow to inject services with any lifetime (transient and scoped) into health checks. This will probably land in the 2.2 release.

When you can use transient and scoped services in health checks, you should register them using a transient lifestyle.