上篇主要介绍IOptions的原理,这篇看下如何使用
定义选项:
public class MyOption { public string Name { get; set; } public int Score { get; set; } }
class Program { static void Main(string[] args) { var services = new ServiceCollection(); services.AddOptions(); services.Configure<MyOption>(option => { option.Name = "Test"; }); var provider = services.BuildServiceProvider(); var myOption = provider.GetService<IOptions<MyOption>>(); Console.WriteLine(myOption.Value.Name); Console.Read(); } }
class Program { static void Main(string[] args) { var services = new ServiceCollection(); services.AddOptions(); services.Configure<MyOption>(option => { option.Name = "Test"; }); services.PostConfigure<MyOption>(option => { option.Score = 100; }); var provider = services.BuildServiceProvider(); var myOption = provider.GetService<IOptions<MyOption>>(); Console.WriteLine($"{myOption.Value.Name}-{myOption.Value.Score}"); Console.Read(); } }
public class MyConfigureOptions : IConfigureOptions<MyOption> { public void Configure(MyOption options) { options.Name = "abc"; } } public class MyConfigureNamedOptions : IConfigureNamedOptions<MyOption> { public void Configure(MyOption options) { options.Score = 1000; } public void Configure(string name, MyOption options) { if (name == "hello") { options.Name = "hello"; } } }
class Program { static void Main(string[] args) { var services = new ServiceCollection(); services.AddOptions(); services.AddTransient<A>(); services.AddTransient<IConfigureOptions<MyOption>>(p => new MyConfigureOptions()); services.AddTransient<IConfigureOptions<MyOption>>(p => new MyConfigureNamedOptions()); var provider = services.BuildServiceProvider(); var myOption = provider.GetService<IOptionsSnapshot<MyOption>>(); Console.WriteLine($"{myOption.Get("hello").Name}"); Console.Read(); } }
补充:
选项从IConfiguration中获取
public class NamedConfigureFromConfigurationOptions<TOptions> : ConfigureNamedOptions<TOptions> where TOptions : class { /// <summary> /// Constructor that takes the <see cref="IConfiguration"/> instance to bind against. /// </summary> /// <param name="name">The name of the options instance.</param> /// <param name="config">The <see cref="IConfiguration"/> instance.</param> public NamedConfigureFromConfigurationOptions(string name, IConfiguration config) : this(name, config, _ => { }) { } /// <summary> /// Constructor that takes the <see cref="IConfiguration"/> instance to bind against. /// </summary> /// <param name="name">The name of the options instance.</param> /// <param name="config">The <see cref="IConfiguration"/> instance.</param> /// <param name="configureBinder">Used to configure the <see cref="BinderOptions"/>.</param> public NamedConfigureFromConfigurationOptions(string name, IConfiguration config, Action<BinderOptions> configureBinder) : base(name, options => config.Bind(options, configureBinder)) { if (config == null) { throw new ArgumentNullException(nameof(config)); } } }
public class ConfigureFromConfigurationOptions<TOptions> : ConfigureOptions<TOptions> where TOptions : class { /// <summary> /// Constructor that takes the <see cref="IConfiguration"/> instance to bind against. /// </summary> /// <param name="config">The <see cref="IConfiguration"/> instance.</param> public ConfigureFromConfigurationOptions(IConfiguration config) : base(options => ConfigurationBinder.Bind(config, options)) { if (config == null) { throw new ArgumentNullException(nameof(config)); } } }
/// <summary> /// Extension methods for adding configuration related options services to the DI container. /// </summary> public static class OptionsConfigurationServiceCollectionExtensions { /// <summary> /// Registers a configuration instance which TOptions will bind against. /// </summary> /// <typeparam name="TOptions">The type of options being configured.</typeparam> /// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param> /// <param name="config">The configuration being bound.</param> /// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns> public static IServiceCollection Configure<TOptions>(this IServiceCollection services, IConfiguration config) where TOptions : class => services.Configure<TOptions>(Options.Options.DefaultName, config); /// <summary> /// Registers a configuration instance which TOptions will bind against. /// </summary> /// <typeparam name="TOptions">The type of options being configured.</typeparam> /// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param> /// <param name="name">The name of the options instance.</param> /// <param name="config">The configuration being bound.</param> /// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns> public static IServiceCollection Configure<TOptions>(this IServiceCollection services, string name, IConfiguration config) where TOptions : class => services.Configure<TOptions>(name, config, _ => { }); /// <summary> /// Registers a configuration instance which TOptions will bind against. /// </summary> /// <typeparam name="TOptions">The type of options being configured.</typeparam> /// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param> /// <param name="config">The configuration being bound.</param> /// <param name="configureBinder">Used to configure the <see cref="BinderOptions"/>.</param> /// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns> public static IServiceCollection Configure<TOptions>(this IServiceCollection services, IConfiguration config, Action<BinderOptions> configureBinder) where TOptions : class => services.Configure<TOptions>(Options.Options.DefaultName, config, configureBinder); /// <summary> /// Registers a configuration instance which TOptions will bind against. /// </summary> /// <typeparam name="TOptions">The type of options being configured.</typeparam> /// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param> /// <param name="name">The name of the options instance.</param> /// <param name="config">The configuration being bound.</param> /// <param name="configureBinder">Used to configure the <see cref="BinderOptions"/>.</param> /// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns> public static IServiceCollection Configure<TOptions>(this IServiceCollection services, string name, IConfiguration config, Action<BinderOptions> configureBinder) where TOptions : class { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } services.AddOptions(); services.AddSingleton<IOptionsChangeTokenSource<TOptions>>(new ConfigurationChangeTokenSource<TOptions>(name, config)); return services.AddSingleton<IConfigureOptions<TOptions>>(new NamedConfigureFromConfigurationOptions<TOptions>(name, config, configureBinder)); } }
从配置文件中获取选项值
class Program { static void Main(string[] args) { var configBuilder = new ConfigurationBuilder(); configBuilder.AddJsonFile("data.json"); var config = configBuilder.Build(); var services = new ServiceCollection(); services.AddOptions(); services.AddTransient<A>(); services.Configure<MyOption>(config); var provider = services.BuildServiceProvider(); var myOption = provider.GetService<IOptions<MyOption>>(); Console.WriteLine(myOption.Value.Name); Console.Read(); } }