Configuration .net核心,n层应用程序,服务层应该依赖于Microsoft.Extensions.Options.dll吗

Configuration .net核心,n层应用程序,服务层应该依赖于Microsoft.Extensions.Options.dll吗,configuration,asp.net-core,.net-core,Configuration,Asp.net Core,.net Core,直截了当的问题是:Microsoft.Extensions.Options.IOOptions是仅在伞形应用程序(本例中为web应用程序)的上下文中使用,还是也在类库中使用 示例: 在一个n层的asp.net核心应用程序中,我们有一个服务层,它依赖于来自appsettings.json文件的一些设置 我们首先从Startup.cs中的以下内容开始: services.Configure<Services.Options.XOptions>(options => {

直截了当的问题是:Microsoft.Extensions.Options.IOOptions是仅在伞形应用程序(本例中为web应用程序)的上下文中使用,还是也在类库中使用

示例:

在一个n层的asp.net核心应用程序中,我们有一个服务层,它依赖于来自
appsettings.json
文件的一些设置

我们首先从Startup.cs中的以下内容开始:

  services.Configure<Services.Options.XOptions>(options =>
  {
    options.OptionProperty1 = Configuration["OptionXSection:OptionXProperty"];
  });
services.Configure(选项=>
{
options.OptionProperty1=配置[“OptionXSection:OptionXProperty”];
});
然后在服务构造函数中:

ServiceConstructor(IOptions<XOptions> xOptions){}
ServiceConstructor(IOptions xOptions){
但这假设在我们的服务层中,我们依赖于
Microsoft.Extensions.Options

我们不确定这是推荐的方式还是有更好的做法


我们的服务类库应该知道DI容器的实现,这让人觉得有点尴尬。

您也可以注册POCO设置以进行注入,但是您会丢失一些与编辑
appsettings.json
相关的功能

services.AddTransient(
provider=>provider.GetRequiredService().Value);
现在,当您在构造函数中注入
XOptions
时,您将获得该类。但是,当您编辑
appsettings.json
时,该值将不会更新,直到下一次解析时才会更新,下一次请求时将解析作用域服务的哪个值,而单例服务的从不

另一方面,注入
IOptionsSnapshot
.Value
将始终为您提供当前设置,即使重新加载
appsettings.json
(假设您使用
.AddJsonFile(“appsettings.json”,reloadOnSave:true)时也是如此

Microsoft.Extensions.Options
package拉入服务/域层的功能保留为w/o的明显原因是创建自己的接口和实现

//在共享服务/域程序集中
公共接口设置为snapshot,其中T:class
{
T值{get;}
}
并在应用程序端(服务/域程序集之外)实现它,即
MyProject.Web
(其中ASP.NET核心和组合根是)

公共类选项SnapshotWrapper:ISettingsSnapshot
{
私有只读IOptionsSnapshot快照;
公共选项SnapshotWrapper(IOptionsSnapshot快照)
{
this.snapshot=snapshot??抛出新的ArgumentNullException(nameof(snapshot));
}
公共T值=>snapshot.Value;
}
并将其注册为

services.AddSingleton(typeof(ISettingsSnapshot),typeof(OptionsSnapshotWrapper));

现在,您已经从服务中删除了对
IOptions
IOptionsSnapshot
的依赖,但保留了它的所有优势,如在编辑appsettings.json时更新选项。当您更改DI时,只需用新的实现替换
选项SnapshotWrapper

在我看来,在任何你认为有用的地方使用IOption都是完全合法的。如果你明天想在其他伞式应用程序中使用你的服务,而这些伞式应用程序使用的是除.net core defaults one之外的DI容器,会发生什么呢?服务类不需要知道DI,它只是有一个construcotr依赖项,服务本身也应该由DI添加,而不是更新。DI适用于所有层除了Startup.cs外,您的类都不应该知道DI容器,在Startup.cs中连接了DI容器。您可以轻松地切换到其他DI容器,而不是默认容器。拥有构造函数依赖关系并不意味着意识到DI@deezg在99.9%中,我不需要重新加载
appsettings.json
,因此我不使用
IOptions
。您可以在这里找到一个类似的问题,涉及这种方法的优点和缺点: