services.Configure <>()或services.AddSingleton()。Get()?

时间:2018-11-22 05:47:35

标签: c# asp.net-core configuration

众所周知,有两种方法可以在ASP.NET Core 2中获取选项类:

  1. 像这样使用services.Configure<>()

    services.AddOption();
    services.Configure<ApplicationOptions>(Configuration.GetSection("applicationSettings"));
    
  2. 或像这样使用services.AddSingleton(Configuration.Get())

    services.AddSingleton(Configuration.GetSection("applicationSettings")
        .Get<ApplicationOptions>());
    

但是这些不同的方法有什么优点或缺点?

2 个答案:

答案 0 :(得分:1)

简短答案:第一种方法添加了Options,第二种方法注册了普通的单例服务

如果可能的话,我总是喜欢选项模式

在幕后,Configure<TOptions>()将调用services.AddSingleton<>()来注册单例服务以配置选项。但是,要配置选项,我们应该始终使用第一种方法。由于Configure<TOptions>(config)(以及所有其他configure<>()方法)将为我们完成所有繁重的工作。 :

  1. 例如,如果我们想为同一类型存储两个不同的实例,那么如何使用普通的单例服务来做到这一点?实际上,这正是命名选项的作用。

  2. 此外,很难根据对applicationSettings.json的文件更改来自动重新加载普通的单例服务。

答案 1 :(得分:1)

使用Configure<ApplicationOptions>允许options pattern。选项模式是一种使用各种配置源配置事物的好方法。在您的示例中,您正在使用Microsoft.Extensions.Configuration源配置ApplicationOptions。但是您也可以同时通过其他来源对其进行配置:

// configure using configuration
services.Configure<ApplicationOptions>(Configuration.GetSection("applicationSettings"));

// then apply a configuration function
services.Configure<ApplicationOptions>(options =>
{
    // overwrite previous values
    options.Foo = "bar";
});

还有其他几种调整配置的方法,例如使用后配置,它使您可以轻松组合利用选项的内容,但可能需要建立某些默认值或后备选项。

选项对象将在使用时进行配置,因此,当您调用services.Configure()时,实际上没有任何配置。而是使用DI容器注册配置。然后,在解析选项后,将调用特定类型的所有配置(这允许组合)。这允许选项还支持更新配置。因此,当您在运行时更新appsettings.json时,选项可以接收更新后的值。

为了使用选项,您需要注入IOptions<ApplicationOptions>(如果需要更新选项,则需要注入IOptionsSnapshot<ApplicationOptions>)。这是options对象的包装,它将调用options模式。


另一方面,调用AddSingleton<ApplicationOptions>仅将单例实例注册为固定值。因此,在DI提供者处注册的是Configuration.GetSection("applicationSettings").Get<ApplicationOptions>()在那个确切时刻返回 的任何值。

这样做的好处是您不需要使用选项模式;不必将IOptions<ApplicationOptions>注入类型,您可以直接依赖ApplicationOptions。因此,您不必依赖选项框架。这对于希望在默认情况下可能不提供选项模式的不同场景中使用的独立库而言是很好的选择。

但是,由于这会注册一个固定的实例,因此您也只能使用这些确切值。更改配置源后,您将无法在以后更新这些值,也无法将一个配置源与其他配置结合使用。