title: How to Use Configuration with ValidateDataAnnotations
body: <p>I've read the Microsoft documentation of fundamentals for <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-2.2" rel="nofollow noreferrer">Options</a> and <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.2" rel="nofollow noreferrer">Configuration</a>, but still can't find the right way to extract configuration into an object while validating data annotations.</p>
  
  <p>One approach I tried in <code>Startup.ConfigureServices</code></p>
  
  <pre><code>services.AddOptions&lt;EmailConfig&gt;().Bind(Configuration.GetSection("Email")).ValidateDataAnnotations();
  </code></pre>
  
  <p>This "should" allow accessing the configuration by adding this in the class constructor: <code>(IOptions&lt;EmailConfig&gt; emailConfig)</code></p>
  
  <p>However it's not working.</p>
  
  <p>Another approach is to add <code>(IConfiguration configuration)</code> to the constructor, but this doesn't allow me to call <code>ValidateDataAnnotations</code>.</p>
  
  <pre><code>configuration.GetSection("Email").Get&lt;EmailConfig&gt;();
  </code></pre>
  
  <p>First question: does the responsibility to bind and validate the configuration belong to the Startup class or to the class using it? If it's used by several classes I'd say it belongs to Startup; and the class could be used in another project with different configuration layout.</p>
  
  <p>Second question: what is the correct syntax to bind and validate the configuration so it can be accessed from the class?</p>
  
  <p>Third question: if I'm validating through data annotations in Startup, then the class using the configuration simply assumes the configuration is valid and I don't put any re-validation whatsoever?</p>
  
  <p><strong>UPDATE: After gaining more experience and reviewing the structure of all my code, I changed my approach to follow standard patterns.</strong></p>
  
  <p>The following code DOES work... but only validates it when used. This can be registered in a class library and won't throw any errors until the particular service is used.</p>
  
  <pre><code>services.AddOptions&lt;EmailConfig&gt;()
      .Bind(configuration.GetSection("Email"))
      .ValidateDataAnnotations();
  </code></pre>
  
  <p>Then, in Configure, I add this to force validation of needed configuration values at startup (CheckNotNull is a custom extension method, what matters is simply that you call IOptions.Value</p>
  
  <pre><code>public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  {
      app?.ApplicationServices.GetService&lt;IOptions&lt;EmailConfig&gt;&gt;().Value.CheckNotNull("Config: Email");
      app?.ApplicationServices.GetService&lt;IOptions&lt;OntraportConfig&gt;&gt;().Value.CheckNotNull("Config: Ontraport");
      ...
  </code></pre>
  
  <p>Then in the class using it</p>
  
  <pre><code>public class EmailService(IOptions&lt;EmailConfig&gt; config)
  </code></pre>