前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[ASP.NET Core 3框架揭秘] Options[3]: Options模型[上篇]

[ASP.NET Core 3框架揭秘] Options[3]: Options模型[上篇]

作者头像
蒋金楠
发布于 2020-02-12 15:25:27
发布于 2020-02-12 15:25:27
82500
代码可运行
举报
文章被收录于专栏:大内老A大内老A
运行总次数:0
代码可运行

通过前面演示的几个实例(配置选项的正确使用方式[上篇]配置选项的正确使用方式[下篇]),我们已经对基于Options的编程方式有了一定程度的了解,下面从设计的角度介绍Options模型。我们演示的实例已经涉及Options模型的3个重要的接口,它们分别是IOptions<TOptions>和IOptionsSnapshot<TOptions>,最终的Options对象正是利用它们来提供的。在Options模型中,这两个接口具有同一个实现类型OptionsManager<TOptions>。Options模型的核心接口和类型定义在NuGet包“Microsoft.Extensions.Options”中。

一、OptionsManager<TOptions>

在Options模式的编程中,我们会利用作为依赖注入容器的IServiceProvider对象来提供IOptions<TOptions>服务或者IOptionsSnapshot<TOptions>服务,实际上,最终得到的服务实例都是一个OptionsManager<TOptions>对象。在Options模型中,OptionsManager<TOptions>相关的接口和类型主要体现在下图中。

下面以上图为基础介绍OptionsManager<TOptions>对象是如何提供Options对象的。如下面的代码片段所示,IOptions<TOptions>接口和IOptionsSnapshot<TOptions>接口的泛型参数的TOptions类型要求具有一个默认的构造函数,也就是说,Options对象可以在无须指定参数的情况下直接采用new关键字进行实例化,实际上,Options最初就是采用这种方式创建的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IOptions<out TOptions> where TOptions: class, new()
{
    TOptions Value { get; }
}

public interface IOptionsSnapshot<out TOptions> : IOptions<TOptions>  where TOptions: class, new()
{
    TOptions Get(string name);
}

IOptions<TOptions>接口通过Value属性提供对应的Options对象,继承它的IOptionsSnapshot<TOptions>接口则利用其Get方法根据指定的名称提供对应的Options对象。OptionsManager<TOptions>针对这两个接口成员的实现依赖其他两个对象,分别通过IOptionsFactory<TOptions>接口和IOptionsMonitorCache<TOptions>接口表示,这也是Options模型的两个核心成员。

作为Options对象的工厂,IOptionsFactory<TOptions>对象负责创建Options对象并对其进行初始化。出于性能方面的考虑,由IOptionsFactory<TOptions>工厂创建的Options对象会被缓存起来,针对Options对象的缓存就由IOptionsMonitorCache<TOptions>对象负责。下面会对IOptionsFactory<TOptions>和IOptionsMonitorCache<TOptions>进行单独讲解,在此之前需要先了解OptionsManager<TOptions>类型是如何定义的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class OptionsManager<TOptions>  :IOptions<TOptions>,  IOptionsSnapshot<TOptions> where TOptions : class, new()
{
    private readonly IOptionsFactory<TOptions> _factory;
    private readonly OptionsCache<TOptions>  _cache =  new OptionsCache<TOptions>();  

    public OptionsManager(IOptionsFactory<TOptions> factory)  => _factory = factory;
    public TOptions Value => this.Get(Options.DefaultName);    
    public TOptions Get(string name)  => _cache.GetOrAdd(name, () => _factory.Create(name));
}

public static class Options
{
    public static readonly string DefaultName = string.Empty;  
}

OptionsManager<TOptions>对象提供Options对象的逻辑基本上体现在上面给出的代码中。在创建一个OptionsManager<TOptions>对象时需要提供一个IOptionsFactory<TOptions>工厂,而它自己还会创建一个OptionsCache<TOptions>(该类型实现了IOptionsMonitorCache<TOptions>接口)对象来缓存Options对象,也就是说,Options对象实际上是被OptionsManager<TOptions>对象以“独占”的方式缓存起来的,后续内容还会提到这个设计细节。

从编程的角度来讲,IOptions<TOptions>接口和IOptionsSnapshot<TOptions>接口分别体现了非具名与具名的Options提供方式,但是对于同时实现这两个接口的OptionsManager<TOptions>来说,提供的Options都是具名的,唯一的不同之处在于以IOptions<TOptions>接口名义提供Options对象时会采用一个空字符串作为名称。默认Options名称可以通过静态类型Options的只读字段DefaultName来获取。

OptionsManager<TOptions>针对Options对象的提供(具名或者非具名)最终体现在其实现的Get方法上。由于Options对象缓存在自己创建的OptionsCache<TOptions>对象上,所以它只需要将指定的Options名称作为参数调用其GetOrAdd方法就能获取对应的Options对象。如果Options对象尚未被缓存,它会利用作为参数传入的Func<TOptions>委托对象来创建新的Options对象,从前面给出的代码可以看出,这个委托对象最终会利用IOptionsFactory<TOptions>工厂来创建Options对象。

二、IOptionsFactory<TOptions>

顾名思义,IOptionsFactory<TOptions>接口表示创建和初始化Options对象的工厂。如下面的代码片段所示,该接口定义了唯一的Create方法,可以根据指定的名称创建对应的Options对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IOptionsFactory<TOptions> where TOptions: class, new()
{
    TOptions Create(string name);
}

OptionsFactory<TOptions>OptionsFactory<TOptions>是IOptionsFactory<TOptions>接口的默认实现。OptionsFactory<TOptions>对象针对Options对象的创建主要分3个步骤来完成,笔者将这3个步骤称为Options对象相关的“实例化”、“初始化”和“验证”。由于Options类型总是具有一个公共默认的构造函数,所以OptionsFactory<TOptions>的实现只需要利用new关键字调用这个构造函数就可以创建一个空的Options对象。当Options对象被实例化之后,OptionsFactory<TOptions>对象会根据注册的一些服务对其进行初始化。Options模型中针对Options对象初始化的工作由如下3个接口表示的服务负责。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IConfigureOptions<in TOptions> where TOptions: class
{    
    void Configure(TOptions options);
}

public interface IConfigureNamedOptions<in TOptions> :  IConfigureOptions<TOptions> where TOptions : class
{
    void Configure(string name, TOptions options);
}

public interface IPostConfigureOptions<in TOptions> where TOptions : class
{    
    void PostConfigure(string name, TOptions options);
}

上述3个接口分别通过定义的Configure方法和PostConfigure方法对指定的Options对象进行初始化,其中,IConfigureNamedOptions<TOptions>和IPostConfigureOptions<TOptions>还指定了Options的名称。由于IConfigureOptions<TOptions>接口的Configure方法没有指定Options的名称,意味着该方法仅仅用来初始化默认的Options对象,而这个默认的Options对象就是以空字符串命名的Options对象。从接口命名就可以看出定义其中的3个方法的执行顺序:定义在IPostConfigureOptions<TOptions>中的PostConfigure方法会在IConfigureOptions<TOptions>和IConfigureNamedOptions<TOptions>的Configure方法之后执行。

当注册的IConfigureNamedOptions<TOptions>服务和IPostConfigureOptions<TOptions>服务完成了对Options对象的初始化之后,IOptionsFactory<TOptions>对象还应该验证最终得到的Options对象是否有效。针对Options对象有效性的验证由IValidateOptions<TOptions>接口表示的服务对象来完成。如下面的代码片段所示,IValidateOptions<TOptions>接口定义的唯一的方法Validate用来对指定的Options对象(参数options)进行验证,而参数name则代表Options的名称。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IValidateOptions<TOptions> where TOptions : class
{
    ValidateOptionsResult Validate(string name, TOptions options);
}

public class ValidateOptionsResult
{
    public static readonly ValidateOptionsResult Success;
    public static readonly ValidateOptionsResult Skip;
    public static ValidateOptionsResult Fail(string failureMessage);

    public bool Succeeded { get; protected set; }
    public bool Skipped { get; protected set; }
    public bool Failed { get; protected set; }
    public string FailureMessage { get; protected set; }
}

Options的验证结果由ValidateOptionsResult类型表示。总的来说,针对Options对象的验证会产生3种结果,即成功、失败和忽略,它们分别通过3个对应的属性来表示(Succeeded、Failed和Skipped)。一个表示验证失败的ValidateOptionsResult对象会通过其FailureMessage属性来描述具体的验证错误。可以调用两个静态只读字段Success和Skip以及静态方法Fail得到或者创建对应的ValidateOptionsResult对象。

Options模型提供了一个名为OptionsFactory<TOptions>的类型作为IOptionsFactory<TOptions>接口的默认实现。对上述3个接口有了基本了解后,对实现在OptionsFactory<TOptions>类型中用来创建并初始化Options对象的实现逻辑比较容易理解了。下面的代码片段基本体现了OptionsFactory<TOptions>类型的完整定义。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class OptionsFactory<TOptions> :IOptionsFactory<TOptions> where TOptions : class, new()
{
    private readonly IEnumerable<IConfigureOptions<TOptions>> _setups;
    private readonly IEnumerable<IPostConfigureOptions<TOptions>> _postConfigures;
    private readonly IEnumerable<IValidateOptions<TOptions>> _validations;

    public OptionsFactory(IEnumerable<IConfigureOptions<TOptions>> setups, IEnumerable<IPostConfigureOptions<TOptions>> postConfigures)
        : this(setups, postConfigures, null)
    { }

    public OptionsFactory(IEnumerable<IConfigureOptions<TOptions>> setups, IEnumerable<IPostConfigureOptions<TOptions>> postConfigures, IEnumerable<IValidateOptions<TOptions>> validations)
    {
        _setups = setups;
        _postConfigures = postConfigures;
        _validations = validations;
    }

    public TOptions Create(string name)
    {
        //步骤1:实例化
        var options = new TOptions();

        //步骤2-1:针对IConfigureNamedOptions<TOptions>的初始化
        foreach (var setup in _setups)
        {
            if (setup is IConfigureNamedOptions<TOptions> namedSetup)
            {
                namedSetup.Configure(name, options);
            }
            else if (name == Options.DefaultName)
            {
                setup.Configure(options);
            }
        }

        //步骤2-2:针对IPostConfigureOptions<TOptions>的初始化
        foreach (var post in _postConfigures)
        {
            post.PostConfigure(name, options);
        }

        //步骤3:有效性验证
        var failedMessages = new List<string>();
        foreach (var validator in _validations)
        {
            var reusult = validator.Validate(name, options);
            if (reusult.Failed)
            {
                failedMessages.Add(reusult.FailureMessage);
            }
        }
        if (failedMessages.Count > 0)
        {
            throw new OptionsValidationException(name, typeof(TOptions),
                failedMessages);
        }
        return options;
    }
}

如上面的代码片段所示,调用构造函数创建OptionsFactory<TOptions>对象时需要提供IConfigureOptions<TOptions>对象、IPostConfigureOptions<TOptions>对象和IValidateOptions<TOptions>对象。在实现的Create方法中,它首先调用默认构造函数创建一个空Options对象,再先后利用IConfigureOptions<TOptions>对象和IPostConfigureOptions<TOptions>对象对这个Options对象进行“再加工”。这一切完成之后,指定的IValidateOptions<TOptions>会被逐个提取出来对最终生成的Options对象进行验证,如果没有通过验证,就会抛出一个OptionsValidationException类型的异常。图7-8所示的UML展示了OptionsFactory<TOptions>针对Options对象的初始化。

三、ConfigureNamedOptions<TOptions>

对于上述3个用来初始化Options对象的接口,Options模型均提供了默认实现,其中,ConfigureNamedOptions<TOptions>类同时实现了IConfigureOptions<TOptions>和IConfigureNamedOptions<TOptions>接口。当我们创建这样一个对象时,需要指定Options的名称和一个用来初始化Options对象的Action<TOptions>委托对象。如果指定了一个非空的名称,那么提供的委托对象将会用于初始化与该名称相匹配的Options对象;如果指定的名称为Null(不是空字符串),就意味着提供的初始化操作适用于所有同类的Options对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ConfigureNamedOptions<TOptions> :IConfigureNamedOptions<TOptions>,IConfigureOptions<TOptions> where TOptions : class
{
    public string Name { get; }
    public Action<TOptions> Action { get; }

    public ConfigureNamedOptions(string name, Action<TOptions> action)
    {
        Name = name;
        Action = action;
    }

    public void Configure(string name, TOptions options)
    {
        if (Name == null || name == Name)
        {
            Action?.Invoke(options);
        }
    }

    public void Configure(TOptions options)  => Configure(Options.DefaultName, options);
}

有时针对某个Options的初始化工作需要依赖另一个服务。比较典型的就是根据当前承载环境(开发、预发和产品)对某个Options对象做动态设置。为了解决这个问题,Options模型提供了一个ConfigureNamedOptions<TOptions, TDep>,其中,第二个反省参数代表依赖的服务类型。如下面的代码片段所示,ConfigureNamedOptions<TOptions, TDep>依然是IConfigureNamedOptions<TOptions>接口的实现类型,它利用Action<TOptions, TDep>对象针对指定的依赖服务对Options做针对性初始化。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ConfigureNamedOptions<TOptions, TDep> : IConfigureNamedOptions<TOptions>
    where TOptions : class
    where TDep : class
{
    public string Name { get; }
    public Action<TOptions, TDep> Action { get; }
    public TDep Dependency { get; }

    public ConfigureNamedOptions(string name, TDep dependency, Action<TOptions, TDep> action)
    {
        Name = name;
        Action = action;
        Dependency = dependency;
    }

    public virtual void Configure(string name, TOptions options)
    {
        if (Name == null || name == Name)
        {
            Action?.Invoke(options, Dependency);
        }
    }

    public void Configure(TOptions options)  => Configure(Options.DefaultName, options);
}

ConfigureNamedOptions<TOptions, TDep>仅仅实现了针对单一服务的依赖,针对Options的初始化可能依赖多个服务,Options模型为此定义了如下所示的一系列类型。这些类型都实现了IConfigureNamedOptions<TOptions>接口,并采用类似于ConfigureNamedOptions<TOptions, TDep>类型的方式实现了Configure方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ConfigureNamedOptions<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> : IConfigureNamedOptions<TOptions>
    where TOptions : class
    where TDep1 : class
    where TDep2 : class
    where TDep3 : class
    where TDep4 : class
    where TDep5 : class
{
    public string Name { get; }
    public TDep1 Dependency1 { get; }
    public TDep2 Dependency2 { get; }
    public TDep3 Dependency3 { get; }
    public TDep4 Dependency4 { get; }
    public TDep5 Dependency5 { get; }
    public Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> Action { get; }

    public ConfigureNamedOptions(string name, TDep1 dependency, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> action);
    public void Configure(TOptions options);
    public virtual void Configure(string name, TOptions options);
}

四、PostConfigureOptions<TOptions>

默认实现IPostConfigureOptions<TOptions>接口的是PostConfigureOptions<TOptions>类型。从给出的代码片段可以看出它针对Options对象的初始化实现方式与ConfigureNamedOptions<TOptions>类型并没有本质的差别。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class PostConfigureOptions<TOptions> : IPostConfigureOptions<TOptions> where TOptions : class
{
    public string Name { get; }
    public Action<TOptions> Action { get; }

    public PostConfigureOptions(string name, Action<TOptions> action)
    {
        Name = name;
        Action = action;
    }

    public void PostConfigure(string name, TOptions options)
    {
        if (Name == null || name == Name)
        {
            Action?.Invoke(options);
        }
    }
}

Options模型同样定义了如下这一系列针对依赖服务的IPostConfigureOptions<TOptions>接口实现。如果针对Options对象的后置初始化操作依赖于其他服务,就可以根据服务的数量选择对应的类型。这些类型针对PostConfigure方法的实现与ConfigureNamedOptions<TOptions, TDep>类型实现Configure方法并没有本质区别。

  • PostConfigureOptions<TOptions, TDep>。
  • PostConfigureOptions<TOptions, TDep1, TDep2>。
  • PostConfigureOptions<TOptions, TDep1, TDep2, TDep3>。
  • PostConfigureOptions<TOptions, TDep1, TDep2, TDep3, TDep4>。
  • PostConfigureOptions<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5>。

五、ValidateOptions<TOptions>

ValidateOptions<TOptions>是对IValidateOptions<TOptions>接口的默认实现。如下面的代码片段所示,创建一个ValidateOptions<TOptions>对象时,需要提供Options的名称和验证错误消息,以及真正用于对Options进行验证的Func<TOptions, bool>对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ValidateOptions<TOptions> : IValidateOptions<TOptions>where TOptions : class
{
    public string Name { get; }
    public string FailureMessage { get; }
    public Func<TOptions, bool> Validation { get; }
    public ValidateOptions(string name, Func<TOptions, bool> validation, string failureMessage);
    public ValidateOptionsResult Validate(string name, TOptions options);
}

对Options的验证同样可能具有对其他服务的依赖,比较典型的依然是针对不同的承载环境(开发、预发和产品)具有不同的验证规则,所以IValidateOptions<TOptions>接口同样具有如下5个针对不同依赖服务数量的实现类型。

  • ValidateOptions<TOptions, TDep>
  • ValidateOptions<TOptions, TDep1, TDep2>
  • ValidateOptions<TOptions, TDep1, TDep2, TDep3>
  • ValidateOptions<TOptions, TDep1, TDep2, TDep3, TDep4>
  • ValidateOptions<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5>

前面介绍了OptionsFactory<TOptions>类型针对Options对象的创建和初始化的实现原理,以及涉及的一些相关的接口和类型,下图基本上反映了这些接口与类型的关系。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-01-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
ASP.NET Core 选项模式源码学习Options IOptions(二)
IOptions是一个接口里面只有一个Values属性,该接口通过OptionsManager实现
HueiFeng
2020/01/22
2.1K0
ASP.NET Core 3.0 : 二十四. 配置的Options模式
上一章讲到了配置的用法及内部处理机制,对于配置,ASP.NET Core还提供了一种Options模式。(ASP.NET Core 系列目录)
FlyLolo
2019/09/29
1.1K0
ASP.NET Core 选项模式源码学习Options Configure(一)
ASP.NET Core 后我们的配置变得更加轻量级了,在ASP.NET Core中,配置模型得到了显著的扩展和增强,应用程序配置可以存储在多环境变量配置中,appsettings.json用户机密等 并可以通过应用程序中的相同界面轻松访问,除此之外,ASP.NET中的新配置系统允许使用Options的强类型设置。
HueiFeng
2020/01/22
2.5K0
[ASP.NET Core 3框架揭秘] Options[5]: 依赖注入
《Options模型》介绍了组成Options模型的4个核心对象以及它们之间的交互关系,读者对如何得到Options对象的实现原理可能不太了解,本篇文章主要介绍依赖注入的相关内容。既然我们能够利用IServiceProvider对象提供的IOptions<TOptions>服务、IOptionsSnapshot<TOptions>服务和IOptionsMonitorCache<TOptions>服务来获取对应的Options对象,那么在这之前必然需要注册相应的服务。回顾《配置选项的正确使用方式》演示的几个实例可以发现,Options模式涉及的API其实不是很多,大都集中在相关服务的注册上。Options模型的核心服务实现在IServiceCollection接口的AddOptions扩展方法。
蒋金楠
2020/02/13
1.7K0
[ASP.NET Core 3框架揭秘] Options[5]: 依赖注入
.Net Core中的Options使用以及源码解析
在.Net Core中引入了Options这一使用配置方式,通常来讲我们会把所需要的配置通过IConfiguration对象配置成一个普通的类,并且习惯上我们会把这个类的名字后缀加上Options。所以我们在使用某一个中间件,或者使用第三方类库时,经常会看到配置对应Options的代码,例如关于Cookie的中间件就会配置CookiePolicyOptions这一个对象。
AI.NET 极客圈
2019/07/19
1.1K0
.net 5.0 Options组件源码解析
本文主要介绍Options组件的原理和源码解析,但是主要介绍常用的一些用法,有一些不常用的模式,本文可能会跳过,因为内容太多.
郑小超.
2022/05/07
9570
.net 5.0 Options组件源码解析
[ASP.NET Core 3框架揭秘] Options[6]: 扩展与定制
由于Options模型涉及的核心对象最终都注册为相应的服务,所以从原则上讲这些对象都是可以定制的,下面提供几个这样的实例。由于Options模型提供了针对配置系统的集成,所以可以采用配置文件的形式来提供原始的Options数据,可以直接采用反序列化的方式将配置文件的内容转换成Options对象。
蒋金楠
2020/02/18
6020
ASP.NET Core的配置(3): 将配置绑定为对象[下篇]
我们在《读取配置信息》通过实例的形式演示了如何利用Options模型以依赖注入的方式直接获取由指定配置节绑定生成的Options对象,我们再次回顾一下当初我们编写的程序。如下面的代码片段所示,基于Options模型的配置绑定的编程基本采用这样的模式:先后调用ServiceCollection的扩展方法AddOption和Configure注册Options模型相关的服务并完成Options类型与指定配置节之间的映射,然后利用由此生成ServiceProvider获得一个类型为IOptions<TOption
蒋金楠
2018/01/15
1.1K0
ASP.NET Core的配置(3): 将配置绑定为对象[下篇]
asp.net core选项Options模块的笔记
这篇博客是写给自己看的。已经不止一次看到AddOptions的出现,不管是在.net core源码还是别人的框架里面,都充斥着AddOptions。于是自己大概研究了下,没有深入,因为,我的功力还是不够,等能力到了再回头研究下。在这里还是要说一遍,因为DI的重要性不言而喻,不必谈的太深,说下自己的理解: 
Ryan_OVO
2023/10/19
2050
[ASP.NET Core 3框架揭秘] Options[7]: 与配置系统的整合
Options模型本身与配置系统完全没有关系,但是配置在大部分情况下会作为绑定Options对象的数据源,所以有必要将两者结合在一起。与《扩展与定制》演示的两个例子一样,针对配置系统的集成同样是通过定制Options模型相应的对象来实现的。具体来说,集成配置系统需要解决如下两个问题:
蒋金楠
2020/02/18
4530
【5min+】更好的选项实践。.Net Core中的IOptions
【五分钟的dotnet】是一个利用您的碎片化时间来学习和丰富.net知识的博文系列。它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net知识等等。
句幽
2020/04/27
9690
深入理解 ASP.NET Core 中的 IOptions
在 ASP.NET Core 中,配置管理是一个核心功能,它允许我们以灵活的方式读取和管理应用程序的配置信息。IOptions 是 ASP.NET Core 提供的一种强大的配置模式,用于将配置数据注入到应用程序的各个部分。通过 IOptions,我们可以轻松地实现配置的解耦、动态更新和依赖注入。
郑子铭
2025/04/23
1090
深入理解 ASP.NET Core 中的 IOptions
.Net Core 中的选项Options
.NetCore的配置选项建议结合在一起学习,不了解.NetCore 配置Configuration的同学可以看下我的上一篇文章 [.Net Core配置Configuration源码研究]
蓝夏
2021/09/09
1K0
.NET Core采用的全新配置系统[3]: “Options模式”下的配置是如何绑定为Options对象
配置的原子结构就是单纯的键值对,并且键和值都是字符串,但是在真正的项目开发中我们一般不会单纯地以键值对的形式来使用配置。值得推荐的做法就是采用《.NET Core采用的全新配置系统[1]: 读取配置数据》最后演示的方式将相关的配置定义成一个Options类型,并采用与类型定义想匹配的结构来定义原始的配置,这样就能利用它们之间的映射关系将读取的配置数据绑定为Options对象,我们将这种编程模式称为“Options模式”。 目录 一、配置绑定 二、扩展方法AddOptions 三、扩展方法Configur
蒋金楠
2018/01/15
7670
.NET Core采用的全新配置系统[3]: “Options模式”下的配置是如何绑定为Options对象
asp.net core之Options
本文将介绍 ASP.NET Core 中的 Options 概念和使用方法。Options 是一种配置管理机制,可以将应用程序的配置信息从代码中分离出来,提高代码的可维护性和可测试性。我们将详细介绍如何定义 Options 类、注册 Options、使用 Options,并提供相应的示例代码。此外,我们还将对 IOptions、IOptionsSnapshot、IOptionsMonitor、IConfigureNamedOptions、OptionsBuilder、IValidateOptions、PostConfigureOptions 等相关接口和类进行说明,并给出使用场景示例。
饭勺oO
2023/10/18
3540
asp.net core之Options
ASP.NET Core 选项模式源码学习Options IOptionsMonitor(三)
IOptionsMonitor 是一种单一示例服务,可随时检索当前选项值,这在单一实例依赖项中尤其有用。IOptionsMonitor用于检索选项并管理TOption实例的选项通知, IOptionsMonitor<TOptions> 支持以下方案:
HueiFeng
2020/01/22
1.7K0
ASP.NET Core 选项模式源码学习Options IOptionsMonitor(三)
学习ASP.NET Core,怎能不了解请求处理管道[2]: 服务器在管道中的“龙头”地位
ASP.NET Core管道由注册的服务器和一系列中间件构成。我们在上一篇中深入剖析了中间件,现在我们来了解一下服务器。服务器是ASP .NET Core管道的第一个节点,它负责完整请求的监听和接收,最终对请求的响应同样也由它完成。[本文已经同步到《ASP.NET Core框架揭秘》之中]
蒋金楠
2022/05/09
5990
学习ASP.NET Core,怎能不了解请求处理管道[2]: 服务器在管道中的“龙头”地位
ASP.NET Core 6框架揭秘实例演示[10]:Options基本编程模式
依赖注入使我们可以将依赖的功能定义成服务,最终以一种松耦合的形式注入消费该功能的组件或者服务中。除了可以采用依赖注入的形式消费承载某种功能的服务,还可以采用相同的方式消费承载配置数据的Options对象,这篇文章演示几种典型的编程模式。(本篇提供的实例已经汇总到《ASP.NET Core 6框架揭秘-实例演示版》)
蒋金楠
2022/05/09
6170
ASP.NET Core 6框架揭秘实例演示[10]:Options基本编程模式
[ASP.NET Core 3框架揭秘]服务承载系统[4]:总体设计[下篇]
在了解了作为服务宿主的IHost接口之后,我们接着来认识一下作为宿主构建者的IHostBuilder接口。如下面的代码片段所示,IHostBuilder接口的核心方法Build用来提供由它构建的IHost对象。除此之外,它还具有一个字典类型的只读属性Properties,我们可以将它视为一个共享的数据容器。
蒋金楠
2020/03/19
6840
ASP.NET Core[源码分析篇] - Authentication认证
  首先看一下我们通常是如何使用微软自带的认证,一般在Startup里面配置我们所需的依赖认证服务,这里通过JWT的认证方式讲解
AI.NET 极客圈
2019/09/03
3.1K1
ASP.NET Core[源码分析篇] - Authentication认证
推荐阅读
相关推荐
ASP.NET Core 选项模式源码学习Options IOptions(二)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验