【NetCore】07-选项框架

1.选项框架-服务组件集成配置的最佳实践

处理服务和配置的关系

1.1 特性

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

1.2 设计原则

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

1.3 建议

  • 为我们的服务设计xxxOptions
  • 使用IOptions< xxxOptions>,IOptionsSnapshot< xxxOptions>,IOptionsMonitor< xxxOptions>作为服务的构造参数
VS 2022  Net 6.0

// 服务定义
namespace OptionsDemo.Services
{
    public interface IOrderService
    {
        int ShowMaxOrderCount();
    }

    public class OrderService : IOrderService
    {
        OrderServiceOptions _options;
        public OrderService(OrderServiceOptions options)
        {
            this._options = options;
        }

        public int ShowMaxOrderCount()
        {
            return _options.MaxOrderCount;
        }
    }

    /// <summary>
    /// 表示需要从配置中读取的值
    /// </summary>
    public class OrderServiceOptions
    {
        public int MaxOrderCount { get; set; } = 100;
    }
}

// 服务注册
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddSingleton<OrderServiceOptions>();
builder.Services.AddSingleton<IOrderService,OrderService>();


// Controller定义
 [HttpGet]
        public int Get([FromServices]IOrderService orderService )
        {
            Console.WriteLine($"orderService.ShowMaxOrderCount : {orderService.ShowMaxOrderCount}");
            return 1;
        }

输出结果:
orderService.ShowMaxOrderCount : 100

如果将值和配置相绑定,需要使用Options框架,修改后代码如下

namespace OptionsDemo.Services
{
    public interface IOrderService
    {
        int ShowMaxOrderCount();
    }
    // 只关心配置的值,不关心值得来源
    public class OrderService : IOrderService
    {
        IOptions<OrderServiceOptions> _options;
        public OrderService(IOptions<OrderServiceOptions> options)
        {
            this._options = options;
        }

        public int ShowMaxOrderCount()
        {
            return _options.Value.MaxOrderCount;
        }
    }

    /// <summary>
    /// 表示需要从配置中读取的值
    /// </summary>
    public class OrderServiceOptions
    {
        public int MaxOrderCount { get; set; } = 100;
    }
}


2.选项数据热更新-让服务感知配置的变化

2.1 关键类型

  • IOptionsMonitor< outTOptions>
  • IOptionsSnapshot< outToptions>

2.2 场景

  • 范围作用域类型使用IOptionsSnapshot
  • 单例服务使用IOptionsMonitor

2.3 通过代码更新选项

  • IPostConfigureOptions< TOptions>

// 服务注册使用Scope模式
builder.Services.AddScope<IOrderService,OrderService>();

 public class OrderService : IOrderService
    {
   		 // 只需将IOptions改为IOptionsSnapshot即可
        IOptionsSnapshot<OrderServiceOptions> _options;
        public OrderService(IOptionsSnapshot<OrderServiceOptions> options)
        {
            this._options = options;
        }

        public int ShowMaxOrderCount()
        {
            return _options.Value.MaxOrderCount;
        }
    }

服务注册为Scope,并且使用IOptionsSnashot读取配置,每次请求都会重新计算并读取配置;
如果服务注册为Singleton,并且使用IOptionsMonitor读取配置,也会在配置发生变化后读取到最新的值;
IOptionsMonitor还有OnChange监听方法,可以监听配置变化,配置变化时可以触发事件,方法会监听运行目录和代码目录,可以使得我们在单例模式下监听到配置的变化

// 动态配置配置项
services.PostConfigure< OrderServiceOptions>(options =>{
	options.MaxOrderCount +=100;
});

3.为选项数据添加验证:避免错误配置的应用接受用户流量

3.1 三种验证方法

  • 直接注册验证函数
  • 实现IValidateOptions< TOptions>
  • 使用Microsoft.Extensions.Options.DataAnnottations
// 1.0
services.AddOptions< OrderServiceOptions>().Configure(options => {
	configuration.Bind(options);
}).Validate(options => {
	return options.MaxOrderCount < =100;
},"MaxOrderCount 不能大于100");

// 2.0 属性数注入
services.AddOptions< OrderServiceOptions>().Configure(options => {
	configuration.Bind(options);
}).ValidateDataAnnotations();

// 修稿Options,定义验证属性
public class OrderServiceOptions
{
	[Range(1,20)]
	public int MaxOrderCount {get;set;} = 100;
}

// 3.0 
public class OrderServiceValidateOptions : IValidateOptions< OrderServiceOptions>
{
	public ValidateOptionsResult Validate()
	{
		if(options.MaxOrderCount > 100)
		{
			return ValidateOptionsResult.Fail("MaxService不能大于100");
		}else{
			return ValidateOptionsResult.Sucess;
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值