Home > Software engineering >  Dynamically create healthchecks based on all services that have a certain interface
Dynamically create healthchecks based on all services that have a certain interface

Time:06-24

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:

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
}
  • Related