title: How to inject or use IConfiguration in Azure Function V3 with Dependency Injection when configuring a service
body: <p>Normally in a .NET Core project I would create a 'boostrap' class to configure my service along with the DI registration commands. This is usually an extension method of <code>IServiceCollection</code> where I can call a method like <code>.AddCosmosDbService</code> and everything necessary is 'self-contained' in the static class containing that method. The key though is that the method gets an <code>IConfiguration</code> from the <code>Startup</code> class.</p>
  
  <p>I've worked with DI in Azure Functions in past but haven't come across this specific requirement yet.</p>
  
  <p>I'm using the <code>IConfiguration</code> to bind to a concrete class with properties matching settings from both my <code>local.settings.json</code> as well as the dev/production application settings when the Function is deployed in Azure.</p>
  
  <h3>CosmosDbClientSettings.cs</h3>
  
  <pre><code>/// &lt;summary&gt;
  /// Holds configuration settings from local.settings.json or application configuration
  /// &lt;/summary&gt;    
  public class CosmosDbClientSettings
  {
      public string CosmosDbDatabaseName { get; set; }
      public string CosmosDbCollectionName { get; set; }
      public string CosmosDbAccount { get; set; }
      public string CosmosDbKey { get; set; }
  }
  </code></pre>
  
  <h3>BootstrapCosmosDbClient.cs</h3>
  
  <pre><code>public static class BootstrapCosmosDbClient
  {
      /// &lt;summary&gt;
      /// Adds a singleton reference for the CosmosDbService with settings obtained by injecting IConfiguration
      /// &lt;/summary&gt;
      /// &lt;param name="services"&gt;&lt;/param&gt;
      /// &lt;param name="configuration"&gt;&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public static async Task&lt;CosmosDbService&gt; AddCosmosDbServiceAsync(
          this IServiceCollection services,
          IConfiguration configuration)
      {
          CosmosDbClientSettings cosmosDbClientSettings = new CosmosDbClientSettings();
          configuration.Bind(nameof(CosmosDbClientSettings), cosmosDbClientSettings);
  
          CosmosClientBuilder clientBuilder = new CosmosClientBuilder(cosmosDbClientSettings.CosmosDbAccount, cosmosDbClientSettings.CosmosDbKey);
          CosmosClient client = clientBuilder.WithConnectionModeDirect().Build();
          CosmosDbService cosmosDbService = new CosmosDbService(client, cosmosDbClientSettings.CosmosDbDatabaseName, cosmosDbClientSettings.CosmosDbCollectionName);
          DatabaseResponse database = await client.CreateDatabaseIfNotExistsAsync(cosmosDbClientSettings.CosmosDbDatabaseName);
          await database.Database.CreateContainerIfNotExistsAsync(cosmosDbClientSettings.CosmosDbCollectionName, "/id");
  
          services.AddSingleton&lt;ICosmosDbService&gt;(cosmosDbService);
  
          return cosmosDbService;
      }
  }
  </code></pre>
  
  <h3>Startup.cs</h3>
  
  <pre><code>public class Startup : FunctionsStartup
  {
  
      public override async void Configure(IFunctionsHostBuilder builder)
      {
          builder.Services.AddHttpClient();
          await builder.Services.AddCosmosDbServiceAsync(**need IConfiguration reference**); &lt;--where do I get IConfiguration?
      }
  }
  </code></pre>
  
  <p>Obviously adding a private field for <code>IConfiguration</code> in <code>Startup.cs</code> won't work as it needs to be populated with something and I've also read that <a href="https://github.com/Azure/azure-functions-host/issues/4464" rel="noreferrer">using DI for <code>IConfiguration</code> isn't a good idea</a>.</p>
  
  <p>I've also tried using the options pattern as described <a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#function-app-provided-services" rel="noreferrer">here</a> and implemented as such:</p>
  
  <pre><code>builder.Services.AddOptions&lt;CosmosDbClientSettings&gt;()
      .Configure&lt;IConfiguration&gt;((settings, configuration) =&gt; configuration.Bind(settings));
  </code></pre>
  
  <p>While this would work to inject an <code>IOptions&lt;CosmosDbClientSettings&gt;</code> to a non-static class, I'm using a static class to hold my configuration work.</p>
  
  <p>Any suggestions on how I can make this work or a possible workaround? I'd prefer to keep all the configuration in one place (bootstrap file).</p>