【问题标题】:IOptions pattern with default dynamic value not working as expected具有默认动态值的 IOptions 模式未按预期工作
【发布时间】:2021-01-13 16:48:46
【问题描述】:

我有一个包含StartDate 字符串配置的类,它是时间戳的yyyyMMdd hh:mm:ss 表示,此字符串可以通过appsettings 或环境变量与ASP.NET 应用程序一样传递,但是当它未设置,我希望它返回当前时间。

public class MyOptions
{
    public string StartDate { get; set; } = DateTime.Now.ToString("yyyyMMdd hh:mm:ss");
}

在我的 Startup 中,我像这样注册这个配置类:

public class Startup
{
    public IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));
        ...
    }
    ...
}

然后我将它注入另一个服务并像这样使用它:

public class SomeOtherService
{
    private readonly MyOptions _options;
    public SomeOtherService(IOptions<MyOptions> options)
    {
        _options = options.Value;
    }
    
    void SomeFunction()
    {
        Console.WriteLine($"StartDate is: {_options.StartDate}");
    }
}

我的 AppSettings(.Development).json 和环境变量都不包含 MyOptions.StartDate 的值

每当我调用 SomeOtherClass.SomeFunction() 时,它都会不断返回我的应用首次启动时的时间戳。

我已将MyOptions 中的StartDate 属性拆分为单独的getter 和setter 类,并注意到在应用程序启动时setter 被击中。它似乎是从DateTime.Now.ToString("yyyyMMdd hh:mm:ss") 读取初始返回值,但随后设置此值,导致设置值在任何连续的 get 调用中返回。

我缺少什么让它在调用时返回当前时间戳?

【问题讨论】:

  • 在您的选项类上创建一个函数,并通过该函数访问您的开始日期,当然还有您的空检查。您的属性只会在您的应用程序启动时被初始化,它不会做您希望它做的事情。如果文件中的设置是您希望即时更改的,您可以考虑注入 IOptionsMonitor 或 IOptionsSnapshot。查看文档,那里有很多很好的信息。 docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/…

标签: c# asp.net .net


【解决方案1】:

我可以使用下面的代码让它工作

services.Configure<MyOptions>(_ => Configuration.GetSection("MyOptions").Bind(_));

appsettings.json 应该有 MyOptions 元素,如下所示

"MyOptions": {"StartDate": "test"}

如果您修改的不是全局 appsettings.json 文件,请检查环境名称是否与特定于环境的 appsettings 匹配。 这意味着如果appsettings.Development.json 具有MyOptions 配置元素,则环境名称必须为Development

【讨论】:

  • 感谢您的回答。不幸的是,我在这样尝试时遇到了同样的错误:(
  • @Alex 我刚刚检查了services.Configure&lt;MyOptions&gt;(Configuration.GetSection("MyOptions"));,发现它也可以。可能您没有在appsettings 文件中设置MyOptions(或将其设置在错误的环境文件中)。请更新我的答案。
猜你喜欢
  • 2014-08-20
  • 1970-01-01
  • 2010-12-30
  • 2016-07-01
  • 2019-01-06
  • 1970-01-01
  • 2014-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多