title: How to get the list of IOptions available from DI in c# Core?
body: <p>Following this post: <a href="https://blog.bredvid.no/validating-configuration-in-asp-net-core-e9825bd15f10" rel="nofollow noreferrer">https://blog.bredvid.no/validating-configuration-in-asp-net-core-e9825bd15f10</a></p>
  
  <p>I m now available to validate the Settings when a service need it. What I would like to do is to validate directly when the server starts in program.cs.</p>
  
  <p>I m not sure how to do it? Is there a way to get the list of services injected in DI then verify if the type is assignable from IOption and register it?</p>
  
  <p>Here is how I add to DI the Settings:</p>
  
  <pre><code>    //App settings
      services.ConfigureAndValidate&lt;AuthenticationSettings&gt;(Configuration);
      services.ConfigureAndValidate&lt;SmtpSettings&gt;(Configuration);
  </code></pre>
  
  <p>The extension code:</p>
  
  <pre><code>public static class IServiceCollectionExtensions
      {
          public static IServiceCollection ConfigureAndValidate&lt;T&gt;(
              this IServiceCollection serviceCollection,
              IConfiguration config,
              string section = null
          ) where T : class
          {
              var configType = typeof(T).Name;
              if (string.IsNullOrEmpty(section)) { 
                  section = configType;
              }
  
              return serviceCollection
                  .Configure&lt;T&gt;(config.GetSection(section))
                  .PostConfigure&lt;T&gt;(settings =&gt;
                  {
                      var configErrors = settings.ValidationErrors().ToArray();
                      if (configErrors.Any())
                      {
                          var aggrErrors = string.Join(",", configErrors);
                          var count = configErrors.Length;
                          throw new ApplicationException($"Found {count} configuration error(s) in {configType}: {aggrErrors}");
                      }
                  });
          }
  
          private static IEnumerable&lt;string&gt; ValidationErrors(this object obj)
          {
              var context = new ValidationContext(obj, serviceProvider: null, items: null);
              var results = new List&lt;ValidationResult&gt;();
              Validator.TryValidateObject(obj, context, results, true);
              foreach (var validationResult in results)
              {
                  yield return validationResult.ErrorMessage;
              }
          }
      }
  </code></pre>
  
  <p>Here is my current launcher:</p>
  
  <pre><code>public class Program
  {
      public static async Task Main(string[] args)
      {
          var webHost = new WebHostBuilder()
              .UseKestrel()
              .UseContentRoot(Directory.GetCurrentDirectory())
              .ConfigureAppConfiguration((hostingContext, config) =&gt;
              {
                  config.AddEnvironmentVariables();
  
                  var env = hostingContext.HostingEnvironment;
  
                  config.SetBasePath(env.ContentRootPath)
                        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
              })
              .ConfigureLogging((hostingContext, logging) =&gt;
              {
                  logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                  logging.AddConsole();
                  logging.AddDebug();
              })
              .UseStartup&lt;Startup&gt;()
              .Build();
  
          using (var scope = webHost.Services.CreateScope())
          {
              var services = scope.ServiceProvider;
  
              /// &lt;---- BEGIN / AN IDEA OF WHAT I WOULD LIKE TO DO ----&gt;
              /// &lt;---- THIS CODE IS NOT WORKING ----&gt;
              var allServices = services.GetAllServices();
              if (allServices != null)
              {
                  foreach (var service in allServices )
                  {
                      if (service.ServiceType.IsAssignableFrom(IOptions))
                      {
                         services.GetRequiredService&lt;service.ServiceType&gt;()
                      }
                  }
              }
              /// &lt;---- END ----&gt;
          }
  
          await webHost.RunAsync();
      }
  }
  </code></pre>
  
  <p>Let me know if you have any suggestions in comment.</p>
  
  <p>Thanks for your help.</p>
  
  <hr>
  
  <p>EDIT 1:
  Thanks Steven for your help, with your answer, it helped me to continue to find an answer, but things are still missing.</p>
  
  <p>now, all my settings inherit from ISettings, like:</p>
  
  <pre><code>public class AuthenticationSettings : ISettings
  {
      [Required]
      public string Issuer { get; set; }
      [Required]
      public string Audience { get; set; }
      [Required]
      public string SecretKey { get; set; }
      [Required]
      public int ExpirationDurationInDays { get; set; }
  }
  </code></pre>
  
  <p>I update Program.cs like: </p>
  
  <pre><code>using Autofac;
  using Autofac.Core;
  
  
  
  var options = services.GetService&lt;ILifetimeScope&gt;()
     .ComponentRegistry
     .Registrations.SelectMany(e =&gt; e.Services)
     .Select(s =&gt; s as TypedService)
     .Where(s =&gt; s.ServiceType.IsGenericType &amp;&amp; s.ServiceType.GetGenericTypeDefinition() == typeof(IConfigureOptions&lt;&gt;))
     .Select(s =&gt; s.ServiceType.GetGenericArguments()[0])
     .Where(s =&gt; typeof(ISettings).IsAssignableFrom(s))
     .ToList();
  </code></pre>
  
  <p>so now I need to instantiate each option in options and get the Value. I m still working on it. let me know if you have any suggestion or the solution :)</p>