title: ASP.NET Core Options Pattern
body: <p>I'm trying to use the Options Pattern described <a href="https://docs.asp.net/en/latest/fundamentals/configuration.html#using-options-and-configuration-objects" rel="nofollow">here</a>, but I'm wanting to be able to get something more complex than just key/value pairs.</p>
  
  <p>Ideally, I'd like to be able to copy my appsettings.json using the <code>Paste JSON as Classes</code>, and then hand off the root class to <code>services.Configure&lt;T&gt;(Configuration)</code> and be done with it.</p>
  
  <p>Here's what I've done:</p>
  
  <p><strong>appsettings.json:</strong></p>
  
  <pre><code>{
    "Data": {
      "ConnectionA": {
        "ConnectionString": "string1"
      },
      "ConnectionB": {
        "ConnectionString": "string2"
      }
    }
  }
  </code></pre>
  
  <p><strong>corresponding classes</strong></p>
  
  <pre><code>public class Data
  {
      public Connectiona ConnectionA { get; set; }
      public Connectionb ConnectionB { get; set; }
  }
  
  public class Connectiona
  {
      public string ConnectionString { get; set; }
  }
  
  public class Connectionb
  {
      public string ConnectionString { get; set; }
  }
  </code></pre>
  
  <p><strong>startup.cs</strong></p>
  
  <pre><code>services.Configure&lt;Data&gt;(Configuration);
  </code></pre>
  
  <p>This returns null objects for <code>ConnectionA</code> and <code>ConnectionB</code> though.</p>
  
  <p>Any suggestions?</p>
  
  <p><strong>full startup.cs per request:</strong></p>
  
  <pre><code>    public Startup(IHostingEnvironment env)
      {
          var builder = new ConfigurationBuilder()
              .SetBasePath(env.ContentRootPath)
              .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
              .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
              .AddEnvironmentVariables();
  
          Configuration = builder.Build();
      }
  
      public IConfigurationRoot Configuration { get; }
  
      // This method gets called by the runtime. Use this method to add services to the container.
      public void ConfigureServices(IServiceCollection services)
      {
          services.AddOptions();
          services.Configure&lt;Data&gt;(Configuration);
  
          // Add framework services.
          services.AddMvc();
      }
  
      // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
      public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
      {
          loggerFactory.AddConsole(Configuration.GetSection("Logging"));
          loggerFactory.AddDebug();
  
          if (env.IsDevelopment())
          {
              app.UseDeveloperExceptionPage();
              app.UseBrowserLink();
          }
          else
          {
              app.UseExceptionHandler("/Home/Error");
          }
  
          app.UseStaticFiles();
          app.UseMvc(routes =&gt;
          {
              routes.MapRoute(
                  name: "default",
                  template: "{controller=User}/{action=Index}/{id?}");
          });
      }
  </code></pre>
  
  <p><strong>Edit</strong>:</p>
  
  <p>This works:</p>
  
  <pre><code>services.Configure&lt;Data&gt;(options =&gt; {
      options.Connectiona = new Connectiona();
      options.Connectiona = new Connectionb();
      options.Connectiona.ConnectionString = Configuration["Data:Connectiona:ConnectionString"];
      options.Connectionb.ConnectionString = Configuration["Data:Connectionb:ConnectionString"];
  });
  </code></pre>
  
  <p>So it looks like I just can't use the <code>services.Configure&lt;Data&gt;(Configuration)</code> extension.</p>