特性

  • 支持单例模式读取配置
  • 支持快照
  • 支持配置变更通知
  • 支持运行时动态修改选项值

设计原则

  • 接口分离原则(LSP),我们的类不应该依赖它不适用的配置
  • 关注点分离(SOC),不同组件、服务、类之间的配置不应相互依赖或耦合

建议

  • 为我们的服务设计XXXOptions
  • 使用IOptions<XXXOptions>IOptionsSnapshot<XXXOptions>IOptionsMonitor<XXXOptions>作为服务构造函数的参数

示例

新建Web应用程序👉命名OptionsDemo👉模板选择API👉新建Services文件夹👉新建OrderService

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. namespace OptionsDemo.Services
  6. {
  7. public interface IOrderService { int ShowMaxOrderCount(); }
  8. public class OrderService : IOrderService
  9. {
  10. private readonly OrderServiceOptions _options;
  11. public OrderService(OrderServiceOptions options)
  12. {
  13. _options = options;
  14. }
  15. public int ShowMaxOrderCount()
  16. {
  17. return _options.MaxOrderCount;
  18. }
  19. }
  20. public class OrderServiceOptions
  21. {
  22. public int MaxOrderCount { get; set; } = 200;
  23. }
  24. }

将其注册

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddSingleton<OrderServiceOptions>();
  4. services.AddSingleton<IOrderService, OrderService>();
  5. services.AddControllers();
  6. }

Controller文件中WeatherForecastControllerGet方法修改为

  1. [HttpGet]
  2. public int Get([FromServices]IOrderService orderService)
  3. {
  4. return orderService.ShowMaxOrderCount();
  5. }

执行输出:image.png
这个200是从OrderServiceOptionsMaxOrderCount属性中获取的,如果说我们需要把这个值跟配置像绑定,怎么去做呢
首先我们需要引入Options框架,实际上AspNetCore已经默认的帮我们把框架引入进来了,命名空间是在Microsoft.Extensions.Options
我们需要修改以下我们的服务入参,将OrderServiceOptions修改为IOptions<OrderServiceOptions>,通过Value获取MaxOrderCount

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Microsoft.Extensions.Options;
  6. namespace OptionsDemo.Services
  7. {
  8. public interface IOrderService { int ShowMaxOrderCount(); }
  9. public class OrderService : IOrderService
  10. {
  11. private readonly IOptions<OrderServiceOptions> _options;
  12. public OrderService(IOptions<OrderServiceOptions> options)
  13. {
  14. _options = options;
  15. }
  16. public int ShowMaxOrderCount()
  17. {
  18. return _options.Value.MaxOrderCount;
  19. }
  20. }
  21. public class OrderServiceOptions
  22. {
  23. public int MaxOrderCount { get; set; } = 200;
  24. }
  25. }

那么注册的时候,不再是把我们的Options类型注册进去,而是用Configure方法。
我们这里需要从配置文件里去读取,将appsetting.json添加一节叫OrderService

  1. {
  2. "Logging": {
  3. "LogLevel": {
  4. "Default": "Information",
  5. "Microsoft": "Warning",
  6. "Microsoft.Hosting.Lifetime": "Information"
  7. }
  8. },
  9. "AllowedHosts": "*",
  10. "OrderService": {
  11. "MaxOrderCount": 10086
  12. }
  13. }

将这一节取出来,并配置给它

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.Configure<OrderServiceOptions>(Configuration.GetSection("OrderService"));
  4. services.AddSingleton<IOrderService, OrderService>();
  5. services.AddControllers();
  6. }

运行输出:image.png