Search code examples
c#asp.netdependency-injectionsingletonhealth-check

Is there a way in ASP.NET to get all singletons?


Is there a way in ASP.NET to get all singletons?

I want to implement a health check which would instantiate all the registered singletons and only after that return a healthy status.

I am trying to get all the singletons from the IServiceProvider, but it seems to have only one method, i.e. the object? GetService(Type serviceType);.

So, maybe someone knows a way in C# to get all singletons?

I am trying to do like so:

_servicesProvider
  .GetServices<object>()
  .Where(service => _servicesProvider.GetService(service.GetType()) == service)

But it seems to also give me back scoped services.

Seems like this:

_servicesProvider
  .GetServices<object>()
  .ToList();
return new HealthCheckResult(HealthStatus.Healthy);

should work. But I am still hoping for a more optimal solution.


Solution

  • I don't believe there is a built in way to do this.

    This answer to a similar question agrees, and suggest reflection as a possible solution.

    Another option is to register your ServiceCollection with itself via .AddSingleton<IServiceCollection>(serviceCollection). You can then inject this or request it from the IServiceProvider and query it to get all the service descriptions with singleton lifetime:

    var serviceCollection = serviceProvider.GetRequiredService<IServiceCollection>();
    var singletons = serviceCollection
        .Where(descriptor => descriptor.Lifetime == ServiceLifetime.Singleton)
        .Select(descriptor => serviceProvider.GetRequiredService(descriptor.ServiceType))
        .ToList();
    
    foreach(object singleton in singletons)
    {
        // do something with the singleton
    }
    

    Depending on your use case it may be better to make your own implemention with a reduced interface, rather than exposing all of IServiceCollection to the consumer of the DI container.