在 Core 2.0 中从 class 库访问 appsettings.json 的设置

Accessing settings from appsettings.json from class library in Core 2.0

我在这里阅读了十几个关于 SO 的问题和至少 4 篇博客文章,但我无法在具有多个 class 库项目的 VS2017 解决方案中使用它。但是,我 可以 让它与一个带有 Web 应用程序和一个 class 库的解决方案一起使用,尽管它的模式与我在文档中找到的模式不同,并且SO.

我的解决方案包含 5 个项目,WebApplication、Testing、Infrastructure、Services、Domain(后三个是 class 库)。

在基础设施项目中,我创建了一个名为 EmailConfigurationSettings 的 class 并在 WebApp 的 StartUp class 中注册了它。

这个 class 在 class 库中:

public class EmailConfigurationSettings
{
    public string Provider { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
}

这是在 WebApp 的 StartUp.cs 中:

services.Configure<EmailConfigurationSettings>(Configuration.GetSection("EmailConfigurationSettings"));
services.AddOptions();

appsettings.json

"EmailConfigurationSettings": {
  "Provider": "gmail",
  "Username": "user@gmail.com",
  "Password": "mypassword" 
} 

我需要服务项目中的设置。但现在我只是想确保我真的能找回它们。下面的代码遵循我发现但生成的所有代码示例:

public class LoadEmailSettingsFromAppSettings
{
    private readonly IOptions<EmailConfigurationSettings> _emailSettings;

    public LoadEmailSettingsFromAppSettings(IOptions<EmailConfigurationSettings> emailSettings)
    {
        _emailSettings = emailSettings;
        Message = "Our provider is " + _emailSettings.Value.Provider;
    }

    public string Message { get; set; }
}

_emailSettings 始终为空

所以我尝试在 TestProject 中对其进行测试:

IOptions<EmailConfigurationSettings> someOptions = Options.Create<EmailConfigurationSettings>(new EmailConfigurationSettings());

嗯,那也是空的。

在另一种解决方案中,带有 WebApp 和一个 class 库的解决方案, 使用我在其中一个博客上发现的略有不同的模式,我实际上可以从 appsettings.json:

检索值
public class AuthMessageSender : IEmailSender, ISmsSender
{
    public AuthMessageSender(IOptions<EmailConfig> emailSettings)
    {
        _emailSettings = emailSettings.Value;
    }

    public EmailConfig _emailSettings { get; }

    public Task SendEmailAsync(string email, string subject, string message)
    {
        Execute(email, subject, message).Wait();
        return Task.FromResult(0);
    }

请注意 IOptions class 有 9 个属性不同,但构造方式与上述模式相同。

但是使用此模式 不会 在多个 class 库项目中工作。我如何理解如何让它在多个 class 库场景中工作?

我不知道为什么他们放弃了 ConfigurationManager,它要容易得多。

在微服务中,您可以简单地绑定到与 json 定义匹配的新对象。所以你会这样做。

var emailConfig = new EmailConfigurationSettings();
Configuration.GetSection("EmailConfigurationSettings").Bind(emailConfig);
services.AddSingleton(emailConfig);

完成此操作后,您所要做的就是在服务层构造函数中请求 EmailConfigurationSettings 的副本。这将为您提供该对象的依赖注入单例。

我会在 "bind" 上设置断点并确保填充电子邮件配置。

这里有一个关于 class 库的有趣答案:

在这部分代码中:

private readonly IOptions<EmailConfigurationSettings> _emailSettings;

public LoadEmailSettingsFromAppSettings(IOptions<EmailConfigurationSettings> emailSettings)
{
    _emailSettings = emailSettings;         

依赖项注入不起作用,因为您在 class 库中,所以您应该保持这种状态。

在您的 webapp 中的某个地方构建 LoadEmailSettingsFromAppSettings

public class SomeClass
{
    public SomeClass(IOptions<EmailConfigurationSettings> emailSettings) // dependency injection works in your webapp
    {
        var loadEmail = new LoadEmailSettingsFromAppSettings(emailSettings); // send EmailSettings to your other class in your class library

        //(...)
    }
}

私有只读应该是:

public IOptions<EmailConfigurationSettings> EmailSettings {get; private set;}

readonly vs get/set properties

我希望是清楚和有帮助的