I have a long set of services that check data, and all under the interface "IDataCheck".
IDataChecks is an empty interface with one method "runCheckAsync"
In a commandline app I do:
IEnumerable<IDataCheck>? services = _serviceProvider.GetServices<IDataCheck>();
foreach (IDataCheck? s in services)
{
DataCheckResult result = await s.RunCheckAsync();
// all kinds of stuff with the result such as proposing to autofix
}
I now want to also present the results of these checks in asp.net core healtchecks using also the healthcheck ui, ref:
- https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks?view=aspnetcore-6.0
- https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks
I do not want to create manually a healthcheck per data check because otherwise the usefulness of having an interface is gone
I also do not want to create one healthcheck only otherwise it will produce a long list of results all in one text only column in the ui since it does not support any formatting.
CodePudding user response:
Solved this , with help from the comment from Guru, on the line before "WebApplication app = builder.Build();" to call:
public static IServiceCollection AddDataHealthChecks(this IServiceCollection services)
{
List<string> dataCheckClassList = new List<string>();
IEnumerable<ServiceDescriptor>? dataServices = services.Where(x => x.ServiceType == typeof(IDataCheck));
foreach (ServiceDescriptor s in dataServices)
{
var fullName = s.ImplementationType?.FullName;
if (fullName is not null)
{
dataCheckClassList.Add(fullName);
}
}
foreach(string fullName in dataCheckClassList)
{
services
.AddHealthChecks()
.AddTypeActivatedCheck<DataQualityHealthCheck>(fullName,
failureStatus: HealthStatus.Degraded,
tags: new[] { "data" },
args: new object[] { fullName });
}
return services;
}
and then in the healtcheck itself :
IDataCheck? service = _serviceProvider
.GetServices<IDataCheck>().FirstOrDefault(x => (x.ToString() == _dataCheckServiceName));
if (service is not null)
{
DataCheckResult result = await service.RunCheckAsync();
// etc
}