Skip to main content
Code Review

Return to Answer

Commonmark migration
Source Link

With your ThemesOptions defined as:

public class ThemesOptions {
 public IEnumerable<string> Themes { get; set; }
}

and Reference #1 Configure simple options with a delegate

public static void AddThemes(this IServiceCollection services, Action<ThemesOptions> configureOptions) {
 //Options bound and configured by a delegate
 services.Configure<ThemesOptions>(configureOptions);
}

Will allow the simple delegate to be used when configuring options services.

//Options bound and configured by a delegate
services.AddThemes(option => {
 option.Themes = new [] { "Theme1", "Theme2" /*, "SomeOtherTheme" */};
});

Now assuming an app settings json file like

{
 "option1": "value1_from_json",
 "option2": -1,
 "Themes": [
 "Theme1", "Theme2"
 ] 
}

and Reference #2 Suboptions configuration

you defined the following

public static void AddThemes(this IServiceCollection services, IConfiguration configuration) {
 // Bind options using a sub-section of the appsettings.json file.
 services.Configure<ThemesOptions>(configuration.GetSection("Themes"));
}

and called like

services.AddThemes(Configuration);

As you rightly stated, it works. Yes. That is because the ThemesOptions class defines a property Themes that holds a collection of strings which would match what GetSection("Themes") would return and thus bind.

Now let's look at the ones that did not work and why they don't

In both cases

services.AddThemes(options => {
 options = Configuration.GetSection("Themes").Get<ThemesOptions>();
});

And:

services.AddThemes(options => Configuration.GetSection("Themes"));

you are trying to set the value of a provided argument to the delegate which change the value of the object and in the second one, nothing is done with the option provided. When using the delegate option the value from the settings file are overridden by the configured delegate which is why Themes property of injected IOptions<ThemesOptions> is null

services.AddThemes(options => {
 options.Themes = Configuration.GetSection("Themes").Get<ThemesOptions>().Themes;
});

works because you are populating the members of the passed parameter which was initialized by the options builder to the delegate.

If this configuration section has a value, that will be used. Otherwise binding by matching property names against configuration keys recursively

Each call to Configure<TOptions> adds an IConfigureOptions<TOptions> service to the service container. When more than one configuration service is enabled, the last configuration source specified wins and sets the configuration value.

With your ThemesOptions defined as:

public class ThemesOptions {
 public IEnumerable<string> Themes { get; set; }
}

and Reference #1 Configure simple options with a delegate

public static void AddThemes(this IServiceCollection services, Action<ThemesOptions> configureOptions) {
 //Options bound and configured by a delegate
 services.Configure<ThemesOptions>(configureOptions);
}

Will allow the simple delegate to be used when configuring options services.

//Options bound and configured by a delegate
services.AddThemes(option => {
 option.Themes = new [] { "Theme1", "Theme2" /*, "SomeOtherTheme" */};
});

Now assuming an app settings json file like

{
 "option1": "value1_from_json",
 "option2": -1,
 "Themes": [
 "Theme1", "Theme2"
 ] 
}

and Reference #2 Suboptions configuration

you defined the following

public static void AddThemes(this IServiceCollection services, IConfiguration configuration) {
 // Bind options using a sub-section of the appsettings.json file.
 services.Configure<ThemesOptions>(configuration.GetSection("Themes"));
}

and called like

services.AddThemes(Configuration);

As you rightly stated, it works. Yes. That is because the ThemesOptions class defines a property Themes that holds a collection of strings which would match what GetSection("Themes") would return and thus bind.

Now let's look at the ones that did not work and why they don't

In both cases

services.AddThemes(options => {
 options = Configuration.GetSection("Themes").Get<ThemesOptions>();
});

And:

services.AddThemes(options => Configuration.GetSection("Themes"));

you are trying to set the value of a provided argument to the delegate which change the value of the object and in the second one, nothing is done with the option provided. When using the delegate option the value from the settings file are overridden by the configured delegate which is why Themes property of injected IOptions<ThemesOptions> is null

services.AddThemes(options => {
 options.Themes = Configuration.GetSection("Themes").Get<ThemesOptions>().Themes;
});

works because you are populating the members of the passed parameter which was initialized by the options builder to the delegate.

If this configuration section has a value, that will be used. Otherwise binding by matching property names against configuration keys recursively

Each call to Configure<TOptions> adds an IConfigureOptions<TOptions> service to the service container. When more than one configuration service is enabled, the last configuration source specified wins and sets the configuration value.

With your ThemesOptions defined as:

public class ThemesOptions {
 public IEnumerable<string> Themes { get; set; }
}

and Reference #1 Configure simple options with a delegate

public static void AddThemes(this IServiceCollection services, Action<ThemesOptions> configureOptions) {
 //Options bound and configured by a delegate
 services.Configure<ThemesOptions>(configureOptions);
}

Will allow the simple delegate to be used when configuring options services.

//Options bound and configured by a delegate
services.AddThemes(option => {
 option.Themes = new [] { "Theme1", "Theme2" /*, "SomeOtherTheme" */};
});

Now assuming an app settings json file like

{
 "option1": "value1_from_json",
 "option2": -1,
 "Themes": [
 "Theme1", "Theme2"
 ] 
}

and Reference #2 Suboptions configuration

you defined the following

public static void AddThemes(this IServiceCollection services, IConfiguration configuration) {
 // Bind options using a sub-section of the appsettings.json file.
 services.Configure<ThemesOptions>(configuration.GetSection("Themes"));
}

and called like

services.AddThemes(Configuration);

As you rightly stated, it works. Yes. That is because the ThemesOptions class defines a property Themes that holds a collection of strings which would match what GetSection("Themes") would return and thus bind.

Now let's look at the ones that did not work and why they don't

In both cases

services.AddThemes(options => {
 options = Configuration.GetSection("Themes").Get<ThemesOptions>();
});

And:

services.AddThemes(options => Configuration.GetSection("Themes"));

you are trying to set the value of a provided argument to the delegate which change the value of the object and in the second one, nothing is done with the option provided. When using the delegate option the value from the settings file are overridden by the configured delegate which is why Themes property of injected IOptions<ThemesOptions> is null

services.AddThemes(options => {
 options.Themes = Configuration.GetSection("Themes").Get<ThemesOptions>().Themes;
});

works because you are populating the members of the passed parameter which was initialized by the options builder to the delegate.

If this configuration section has a value, that will be used. Otherwise binding by matching property names against configuration keys recursively

Each call to Configure<TOptions> adds an IConfigureOptions<TOptions> service to the service container. When more than one configuration service is enabled, the last configuration source specified wins and sets the configuration value.

Source Link
Nkosi
  • 3.3k
  • 17
  • 25

With your ThemesOptions defined as:

public class ThemesOptions {
 public IEnumerable<string> Themes { get; set; }
}

and Reference #1 Configure simple options with a delegate

public static void AddThemes(this IServiceCollection services, Action<ThemesOptions> configureOptions) {
 //Options bound and configured by a delegate
 services.Configure<ThemesOptions>(configureOptions);
}

Will allow the simple delegate to be used when configuring options services.

//Options bound and configured by a delegate
services.AddThemes(option => {
 option.Themes = new [] { "Theme1", "Theme2" /*, "SomeOtherTheme" */};
});

Now assuming an app settings json file like

{
 "option1": "value1_from_json",
 "option2": -1,
 "Themes": [
 "Theme1", "Theme2"
 ] 
}

and Reference #2 Suboptions configuration

you defined the following

public static void AddThemes(this IServiceCollection services, IConfiguration configuration) {
 // Bind options using a sub-section of the appsettings.json file.
 services.Configure<ThemesOptions>(configuration.GetSection("Themes"));
}

and called like

services.AddThemes(Configuration);

As you rightly stated, it works. Yes. That is because the ThemesOptions class defines a property Themes that holds a collection of strings which would match what GetSection("Themes") would return and thus bind.

Now let's look at the ones that did not work and why they don't

In both cases

services.AddThemes(options => {
 options = Configuration.GetSection("Themes").Get<ThemesOptions>();
});

And:

services.AddThemes(options => Configuration.GetSection("Themes"));

you are trying to set the value of a provided argument to the delegate which change the value of the object and in the second one, nothing is done with the option provided. When using the delegate option the value from the settings file are overridden by the configured delegate which is why Themes property of injected IOptions<ThemesOptions> is null

services.AddThemes(options => {
 options.Themes = Configuration.GetSection("Themes").Get<ThemesOptions>().Themes;
});

works because you are populating the members of the passed parameter which was initialized by the options builder to the delegate.

If this configuration section has a value, that will be used. Otherwise binding by matching property names against configuration keys recursively

Each call to Configure<TOptions> adds an IConfigureOptions<TOptions> service to the service container. When more than one configuration service is enabled, the last configuration source specified wins and sets the configuration value.

lang-cs

AltStyle によって変換されたページ (->オリジナル) /