可注入的ApplicationConfig服务

时间:2019-03-28 15:04:59

标签: c# asp.net-core-webapi

我想要一种我可以注入的服务-在我的示例中可以通过GetService获得-该服务包含我的appsettings.json文件中的设置。

appsettings.json片段如下所示:

  "ExternalInterfaces": [
      {
        "Name": "name1",
        "BaseUrl": "https://www.baseurl1.svc"
      },
      {
        "Name": "name2",
        "BaseUrl": "https://www.baseurl2.svc"
      }
    ]

为此,我具有以下接口:

using System.Collections.Generic;

namespace Infrastructure.Settings
{
    public interface IExternalInterfaceSettingsCollection
    {
        IReadOnlyCollection<IExternalInterfaceSettings> Settings { get; set; }
    }
}

namespace Infrastructure.Settings
{
    public interface IExternalInterfaceSettings
    {
        string Name { get; set; }
        string BaseUrl { get; set; }
    }
}

和以下相应的类:

using System.Collections.Generic;

namespace Infrastructure.Settings
{
    public class ExternalInterfaceSettingsCollection : IExternalInterfaceSettingsCollection
    {
        public IReadOnlyCollection<IExternalInterfaceSettings> Settings { get; set; }
    }
}
namespace Infrastructure.Settings
{
    public class ExternalInterfaceSettings : IExternalInterfaceSettings
    {
        const string DefaultName = "newExternalInterface";
        const string DefaultBaseUrl = "";

        public string Name { get; set; } = DefaultName;
        public string BaseUrl { get; set; } = DefaultBaseUrl;
    }
}

在我的Startup.cs中,我有这个(肯定会被调用,没有例外):

services.Configure<IExternalInterfaceSettingsCollection>(settings => _configuration.GetSection("ExternalInterfaces").Bind(settings));

,然后按以下方式消耗它:

var externalInterfaceConfiguration = app.ApplicationServices.GetService<ExternalInterfaceSettingsCollection>();
var Setting1BaseUrl = externalInterfaceConfiguration.Settings
    .SingleOrDefault(s => s.Name == "name1")?.BaseUrl;

但是,在最后三行中,externalInterfaceConfiguration始终为空。

我显然缺少了一些东西,但看不到。有任何线索吗?

1 个答案:

答案 0 :(得分:2)

您已经注册IExternalInterfaceSettings,但是您正在尝试检索ExternalInterfaceSettings。集合中没有此类服务,因此结果为null(因为您使用了GetService<T>)。如果您使用过GetRequiredService<T>,那么将会抛出一个异常告诉您。

然后,选项模式并不意味着要绑定到接口。整个想法是,您要绑定到代表一组特定设置的POCO。如果您想使用接口,我想那是您的特权,但是它不适用于选项配置。换句话说,您需要以下内容:

services.Configure<ExternalInterfaceSettings>(Configuration.GetSection("ExternalInterfaces"));

(注意,Bind的操作重载是多余的。您可以直接通过config节。)

这样,您将可以请求类似IOptions<ExternalInterfaceSettings>的请求,但是仍然不能直接从服务集合中获取ExternalInterfaceSettings。如果您想要那个功能,则需要添加一个额外的服务注册(这次可以使用一个接口):

services.AddScoped<IExternalInterfaceSettings, ExternalInterfaceSettings>(p =>
    p.GetRequiredService<IOptions<ExternalInterfaceSettings>>().Value);