简体   繁体   English

需要IConfigurationRoot的ASP.NET Core 2.x注册服务-无法访问配置数据

[英]ASP.NET Core 2.x Register service that requires IConfigurationRoot - cannot access configuration data

Configuration is registered in my app in Program.cs like so 像这样在我的应用程序中的Program.cs中注册配置

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                   .ConfigureAppConfiguration((hostingContext, config) =>
                   {
                       config.AddJsonFile("appsettings.secret.json", optional: true, reloadOnChange: true);
                   })
                   .UseStartup<Startup>()
                   .ConfigureLogging(logging =>
                   {override configuration in NLog.config

                       logging.ClearProviders();
                       logging.SetMinimumLevel(LogLevel.Trace);
                   })
                   .UseNLog(); // NLog: setup NLog for Dependency injection;

I have a class which requires an instance of IConfigurationRoot 我有一个需要IConfigurationRoot实例的类

public class ConfiguredKeyDataProtectionProvider : IDataProtectionProvider
{
    // Example configuration required for use of this class

    // {
    //     "ConfiguredKeyDataProtectionProvider": {
    //         "Key": {
    //             "TestPurpose": "asda2516shah"
    //         }
    //     }
    // }

    private readonly IConfigurationRoot _configurationRoot;

    public ConfiguredKeyDataProtectionProvider(IConfigurationRoot configurationRoot)
    {
        _configurationRoot = configurationRoot;
    }

    public IDataProtector CreateProtector(string purpose)
    {
        string encryptionKey = _configurationRoot.GetValue<string>("ConfiguredKeyDataProtectionProvider:Key:" + purpose);

        return new ConfiguredKeyDataProtector(encryptionKey);
    }
}

I'm trying to register the instance of IConfiguredKeyDataProtectionProvider via DI. 我正在尝试通过DI注册IConfiguredKeyDataProtectionProvider的实例。 I'm expecting that having registered an instance of IConfiguration root (note that reading of config files is duplicated in StartUp.cs - not sure if this is necessary), IConfiguredKeyDataProtectionProvider will be able to see the configuration data, but this appears not to be the case. 我期望已经注册了IConfiguration根实例(请注意,在StartUp.cs中重复读取配置文件-不确定是否有必要),IConfiguredKeyDataProtectionProvider将能够看到配置数据,但这似乎不是案子。

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var configurationRoot = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddJsonFile("appsettings.secret.json", optional: true, reloadOnChange: true)
            .Build();

        Configuration = configurationRoot;
    }

    public IConfigurationRoot Configuration { get; set; }

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IConfigurationRoot>(Configuration);

        //...

        services.AddTransient<IDataProtectionProvider, ConfiguredKeyDataProtectionProvider>();

How should I correctly configure my application so that classes with IConfigurationRoot on the constructor can be registered via dependency injection? 我应该如何正确配置我的应用程序,以便可以通过依赖注入来注册构造函数上具有IConfigurationRoot的类?

Not sure why you need the IConfigurationRoot interface, but since you have already built an instance of IConfigurationRoot before constructing the host, you could register the root as an singleton service by .ConfigureServices(services =>{services.AddSingleton<IConfigurationRoot>(configRoot);}) : 不确定为什么需要IConfigurationRoot接口,但是由于在构造主机之前已经构建了IConfigurationRoot实例, 因此可以通过.ConfigureServices(services =>{services.AddSingleton<IConfigurationRoot>(configRoot);})将根注册为单例服务.ConfigureServices(services =>{services.AddSingleton<IConfigurationRoot>(configRoot);})

Also, there's no need to build the configuration twice, simply call UseConfiguration(congfigRoot) . 另外,无需两次构建配置,只需调用UseConfiguration(congfigRoot)

public static IWebHostBuilder CreateWebHostBuilder(string[] args) {

    // build the root 
    var configRoot = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false)
        // ...
        .Build();

    var builder = new WebHostBuilder();
    return builder
        // reuse the configRoot
        .UseConfiguration(configRoot)
        // register the configRoot as a singleton service
        .ConfigureServices(services =>{
            services.AddSingleton<IConfigurationRoot>(configRoot);
        })
        .UseStartup<Startup>()
        .ConfigureLogging(logging => {   
            //override configuration in NLog.config
            logging.ClearProviders();
            logging.SetMinimumLevel(LogLevel.Trace);
        })
        .UseKestrel();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM