我正在尝试使用新的ASP.NET Code 2.2 Healthchecks功能。
在.net博客的link中,它显示了一个示例:
public void ConfigureServices(IServiceCollection services)
{
//...
services
.AddHealthChecks()
.AddCheck(new SqlConnectionHealthCheck("MyDatabase", Configuration["ConnectionStrings:DefaultConnection"]));
//...
}
public void Configure(IApplicationBuilder app)
{
app.UseHealthChecks("/healthz");
}
我可以添加实现Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck
接口的自定义检查。但是,由于我需要向AddCheck
方法提供实例而不是类型,并且它需要在ConfigureServices
方法内部运行,因此无法在自定义检查器中注入任何依赖项。
有什么办法可以解决此问题?
答案 0 :(得分:5)
如何在ASP.NET Core健康检查中注入依赖项。
如果我们以正确的顺序注册我们的服务,那么SomeDependency
将可以注入到SomeHealthCheck
构造函数中,并且SomeHealthCheck
将作为运行状况检查功能的一部分运行。 / p>
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks();
services.AddSingleton<SomeDependency>();
// register the custom health check
// after AddHealthChecks and after SomeDependency
services.AddSingleton<IHealthCheck, SomeHealthCheck>();
}
comment in the Health Check samples指出:
所有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!"));
}
}
此示例也是available on GitHub here。
答案 1 :(得分:3)
从.NET Core 3.0开始,注册更加简单,并且可以简化为
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks();
services.AddSingleton<SomeDependency>();
services.AddCheck<SomeHealthCheck>("mycheck");
}
请注意,在使用引擎需要使用的内容时,您不再遇到 singleton 与 transient 的冲突。
支票的名称是必填项,因此您必须领一张。
accepted asnwer似乎不再起作用。
答案 2 :(得分:2)
除了Shaun的答案:还有一个open pull-request,它可以将任何生命周期(瞬态和作用域)的服务注入到运行状况检查中。这可能会在2.2版本中发布。
当您可以在运行状况检查中使用临时服务和作用域服务时,应register them using a transient lifestyle。
答案 3 :(得分:0)
我在ASP.NET Core 3.1 Web API中为此苦苦挣扎,因为我遵循上述典型的DI方法,方法是:
services.AddHealthChecks();
services.AddSingleton<IHealthCheck, MyHealthCheck1>();
services.AddSingleton<IHealthCheck, MyHealthCheck2>();
不幸的是,由于未调用IHealthCheck实现,因此在ASP.NET Core 3.1中似乎实际上不起作用。
相反,我必须在Startup.ConfigureServices()中执行以下操作:
services.AddHealthChecks()
.AddCheck<MyHealthCheck1>("My1-check",
HealthStatus.Unhealthy,
new string[] { "tag1" })
.AddCheck<MyHealthCheck2>("My2-check",
HealthStatus.Unhealthy,
new string[] { "tag2" });
然后在Startup.Configure()中,我还按如下方式调用MapHealthChecks():
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHealthChecks("/hc");
});