如何在ASP.NET核心运行状况检查中注入依赖项

lmc*_*iro 8 c# dependency-injection health-monitoring .net-core asp.net-core

我正在尝试使用新的ASP.NET Code 2.2 Healthchecks功能.

在.net博客的此链接中,它显示了一个示例:

public void ConfigureServices(IServiceCollection services)
{
    //...
    services
        .AddHealthChecks()
        .AddCheck(new SqlConnectionHealthCheck("MyDatabase", Configuration["ConnectionStrings:DefaultConnection"]));
    //...
}

public void Configure(IApplicationBuilder app)
{
    app.UseHealthChecks("/healthz");
}
Run Code Online (Sandbox Code Playgroud)

我可以添加实现该Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck接口的自定义检查.但是因为我需要向AddCheck方法提供实例而不是类型,并且需要在ConfigureServices方法内部运行,所以我不能在自定义检查器中注入任何依赖项.

有没有办法解决这个问题?

Pie*_*ier 9

从 .NET Core 3.0 开始,注册更简单,归结为

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

请注意,当您使用引擎需要使用的内容时,您不再有单例瞬态冲突。

支票的名称是强制性的,因此您必须选择一张。

虽然接受的 asnwer似乎不再起作用。


Sha*_*tin 6

简答

如何在ASP.NET核心运行状况检查中注入依赖项.

如果我们以正确的顺序注册我们的服务,那么SomeDependency将可以注入SomeHealthCheck构造函数,并将SomeHealthCheck作为运行状况检查功能的一部分运行.

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

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

更多细节

一个健康检查样品中评论说:

所有IHealthCheck服务都可用于健康检查服务和中间件.我们建议将所有健康检查注册为Singleton服务.

完整样本

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!"));
    }
}
Run Code Online (Sandbox Code Playgroud)

此示例也可以在GitHub上找到.

  • 这是一个很好的答案,尽管有点过时(请注意下面 Henk 的答案) - 您现在可以将任何生命周期的服务注入健康检查,以及使用像 `services.AddHealthChecks().AddCheck&lt;ApiHealthCheck 这样的语法自动注册您的健康检查&gt;(“API”);` (3认同)