Asp.Net Core 中的 Options

Asp.Net Core 中的 Options

原文地址: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-5.0

配置类设计软件工程原则:封装(配置类只依赖与之相关的配置)与隔离(配置类互不依赖)

Options 接口

  • IOptions<TOptions>:
  • IOptionsSnapshot<TOptions>: scoped 设计用于被transient 和 scoped 的类依赖
  • IOptionsMonitor<TOptions>: singleton 设计用于对被单例的类依赖
  • IOptionsFactory<TOptions>:
  • IConfigureOptions<TOptions>
  • IPostConfigureOptions<TOptions>
  • IConfigureNamedOptions<TOptions>
  • IOptionsMonitorCache
  • IOptionsMonitor<TOptions>
"Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }
public class PositionOptions //非抽象类,且必须有无参构造函数
{
    public const string Position = "Position"; //field 不绑定

    public string Title { get; set; } // property + read-write + public 绑定
    public string Name { get; set; }
}

绑定方式 1 : 读取最新的配置信息

var positionOptions = new PositionOptions();
Configuration.GetSection(PositionOptions.Position).Bind(positionOptions); //Configuration is ICongiruation

绑定方式 2: 读取最新的配置信息

var positionOptions = Configuration.GetSection(PositionOptions.Position).Get<PositionOptions>();

绑定方式 3:读取一开始的配置信息

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<PositionOptions>(Configuration.GetSection(PositionOptions.Position));
    
}
public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }   
}

绑定方式 4:读取最新的配置信息,scoped 生命周期

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
}
public class TestSnapModel : PageModel
{
    private readonly MyOptions _snapshotOptions;

    public TestSnapModel(IOptionsSnapshot<MyOptions> snapshotOptionsAccessor)
    {
        _snapshotOptions = snapshotOptionsAccessor.Value;
    }   
}

绑定方式 5:读取最新的配置信息

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
}
public class TestMonitorModel : PageModel
{
    private readonly IOptionsMonitor<MyOptions> _optionsDelegate;

    public TestMonitorModel(IOptionsMonitor<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.CurrentValue.Option1} \n" +
                       $"Option2: {_optionsDelegate.CurrentValue.Option2}");
    }
}

绑定方式 6:

{
  "TopItem": {
    "Month": {
      "Name": "Green Widget",
      "Model": "GW46"
    },
    "Year": {
      "Name": "Orange Gadget",
      "Model": "OG35"
    }
  }
}
public class TopItemSettings
{
    public const string Month = "Month";
    public const string Year = "Year";

    public string Name { get; set; }
    public string Model { get; set; }
}
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<TopItemSettings>(TopItemSettings.Month,
                                       Configuration.GetSection("TopItem:Month"));
    services.Configure<TopItemSettings>(TopItemSettings.Year,
                                        Configuration.GetSection("TopItem:Year"));
}
public class TestNOModel : PageModel
{
    private readonly TopItemSettings _monthTopItem;
    private readonly TopItemSettings _yearTopItem;

    public TestNOModel(IOptionsSnapshot<TopItemSettings> namedOptionsAccessor)
    {
        _monthTopItem = namedOptionsAccessor.Get(TopItemSettings.Month);
        _yearTopItem = namedOptionsAccessor.Get(TopItemSettings.Year);
    }
}

所有选项都是命名实例。 IConfigureOptions<TOptions> 实例将被视为面向 Options.DefaultName 实例,即 string.Empty。

Options

依赖注入

方法 1(绑定方式 7)

services.AddOptions<MyOptions>("optionalName")
    .Configure<Service1, Service2, Service3, Service4, Service5>(
        (o, s, s2, s3, s4, s5) => 
            o.Property = DoSomethingWith(s, s2, s3, s4, s5));

方法 2 (绑定方式 8)

public class OptionsA: IConfigureOptions<TOptions>{}
service.Add<IConfigureOptions<TOptions>, OptionsA>();
public class OptionsB: IConfigureNamedOptions<TOptions>{}
service.Add<IConfigureNamedOptions<TOptions>, OptionsB>();

validation 验证

{
  "MyConfig": {
    "Key1": "My Key One",
    "Key2": 10,
    "Key3": 32
  }
}
public class MyConfigOptions
{
    public const string MyConfig = "MyConfig";

    [RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$")]
    public string Key1 { get; set; }
    [Range(0, 1000,
        ErrorMessage = "Value for {0} must be between {1} and {2}.")]
    public int Key2 { get; set; }
    public int Key3 { get; set; }
}
services.AddOptions<MyConfigOptions>()
            .Bind(Configuration.GetSection(MyConfigOptions.MyConfig))
            .ValidateDataAnnotations().Validate(config =>
        {
            if (config.Key2 != 0)
            {
                return config.Key3 > config.Key2;
            }

            return true;
        }, "Key3 must be > than Key2."); 
class MyConfigValidation : IValidateOptions<MyConfigOptions>
{
    public ValidateOptionsResult Validate(string name, MyConfigOptions options){}
}
services.Configure<MyConfigOptions>(Configuration.GetSection(
                                        MyConfigOptions.MyConfig));
services.TryAddEnumerable(ServiceDescriptor.Singleton<IValidateOptions
                              <MyConfigOptions>, MyConfigValidation>());

PostConfiguration

services.PostConfigure<MyOptions>(myOptions => //default name instances
{
    myOptions.Option1 = "post_configured_option1_value";
});
services.PostConfigure<MyOptions>("named_options_1", myOptions => //named instances
{
    myOptions.Option1 = "post_configured_option1_value";
});
services.PostConfigureAll<MyOptions>(myOptions => //all instances
{
    myOptions.Option1 = "post_configured_option1_value";
});

启动时获取配置值

IOptions<TOptions> and IOptionsMonitor<TOptions> 都可用于Configure 方法, 但是不可用于 ConfigureServices

public void Configure(IApplicationBuilder app, 
    IOptionsMonitor<MyOptions> optionsAccessor)
{
    var option1 = optionsAccessor.CurrentValue.Option1;
}

原文地址:https://www.cnblogs.com/ArvinZhao/p/14592364.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


数组的定义 Dim MyArray MyArray = Array(1‚5‚123‚12‚98) 可扩展数组 Dim MyArray() for i = 0 to 10
\'参数: \'code:要检测的代码 \'leixing:html或者ubb \'nopic:代码没有图片时默认值
演示效果: 代码下载: 点击下载
环境:winxp sp2 ,mysql5.0.18,mysql odbc 3.51 driver 表采用 myisam引擎。access 2003  不同的地方: 
其实说起AJAX的初级应用是非常简单的,通俗的说就是客户端(javascript)与服务端(asp或php等)脚本语言的数据交互。
<% ’判断文件名是否合法 Function isFilename(aFilename)  Dim sErrorStr,iNameLength,i  isFilename=TRUE
在调用的时候加入判断就行了. {aspcms:navlist type=0 } {if:[navlist:i]<6} < li><a href=\"[navlist:link]\" target=\"_top\">[navlist:name]</a> </li>
导航栏调用 {aspcms:navlist type=0}     <a href=\"[navlist:link]\">[navlist:name]</a>
1.引入外部文件: {aspcms:template src=infobar.html} 2.二级下拉菜单 <ul class=\"nav\">
downpic.asp页面:  <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
Cookies是数据包,可以让网页具有记忆功能,在某台电脑上记忆一定的信息。Cookies的工作原理是,第一次由服务器端写入到客户端的系统中。以后每次访问这个网页,都是先由客户端将Cookies发送到服务器端,再由服务器端
很简单,在需要调用的地方用这种模式 {aspcms:content sort={aspcms:sortid} num=17 order=isrecommend}
网站系统使用ACCESS数据库时,查询时怎么比较日期和时间呢?为什么常常比较出来却是错误的呢?比如早的日期比迟的日期大?
str1=\"1235,12,23,34,123,21,56,74,1232\" str2=\"12\" 问题:如何判断str2是否存在str1中,要求准确找出12,不能找出str1中的1235、123、1232
实例为最新版本的kindeditor 4.1.5. 主要程序: <% Const sFileExt=\"jpg|gif|bmp|png\" Function ReplaceRemoteUrl(sHTML,sSaveFilePath,sFileExt)
用ASP实现搜索引擎的功能是一件很方便的事,可是,如何实现类似3721的智能搜索呢?比如,当在搜索条件框内输入“中国人民”时,自动从中提取“中国”、“人民”等关键字并在数据库内进行搜索。看完本文后,你就可以发
首先感谢ASPCMS官网注册用户xing0203的辛苦付出!一下为久忆YK网络转载原创作者xing0203的文章内容!为了让小白更加清楚的体验替换过程,久忆YK对原文稍作了修改!
数据库连接: <% set conn=server.createobject(\"adodb.connection\") conn.open \"driver={microsoft access driver (*.mdb)};dbq=\"&server.mappath(\"数据库名\")
第1步:修改plugins下的image/image.js 找到\'<input type=\"button\" class=\"ke-upload-button\" value=\"\' + lang.upload + \'\" />\',
asp函数: <% Const sFileExt=\"jpg|gif|bmp|png\" Function ReplaceRemoteUrl(sHTML,sSaveFilePath,sFileExt)