具有其他依赖项的 ConfigurationProvider
Posted
技术标签:
【中文标题】具有其他依赖项的 ConfigurationProvider【英文标题】:ConfigurationProvider with other dependencies 【发布时间】:2020-09-16 16:40:43 【问题描述】:我已经实现了我的自定义 IConfigurationProvider 和 IConfigurationSource。
public class MyConfigurationSource : IConfigurationSource
public string Foo get; set;
public IConfigurationProvider Build(IConfigurationBuilder builder)
return new MyConfigurationProvider(this);
internal class MyConfigurationProvider : ConfigurationProvider
public MyConfigurationSource Source get; ;
public MyConfigurationProvider()
Source = source
public override void Load()
// I'd like to assign here my configuration data by using some dependencies
Data = ....
我在 Startup 构造函数中构建我的配置(我覆盖了 CreateDefaultBuilder
创建的配置):
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.env.EnvironmentName.json", optional: true)
.AddEnvironmentVariables()
.AddMyConfiguration("myfoovalue")
.Build();
扩展方法:
public static IConfigurationBuilder AddMyConfiguration(this IConfigurationBuilder builder, string foo)
return builder.Add(new MyConfigurationSource
Foo = url
);
我希望我能以某种方式注入要在Load
方法中使用的服务。这里的问题是配置build
是在Startup构造函数中完成的。我只能注入在此构造函数中可用的依赖项:IWebHostEnvironment
、IHostEnvironment
、IConfiguration
以及我在构建 WebHost 时添加的所有依赖项。当我调用AddMyConfiguration
扩展方法时,也必须传递这些依赖项。我怎么能使用当时甚至不存在的依赖项?
【问题讨论】:
【参考方案1】:回答有点晚了。
很明显,在MyConfigurationSource
/MyConfigurationProvider
中无法使用使用Startup.ConfigureServices
构建的容器,因为在调用ConfigurationBuilder.Build
时,还没有调用ServiceCollection.BuildServiceProvider
。
典型的解决方法是创建另一个具有所需配置的IServiceProvider
实例并在MyConfiguration...
中使用它。
类似
internal class MyConfigurationProvider : ConfigurationProvider
public MyConfigurationSource Source get; ;
public MyConfigurationProvider()
Source = source;
ServiceProvider = BuildServiceProvider();
public override void Load()
// I'd like to assign here my configuration data by using some dependencies
Data = ServiceProvider.GetRequiredService<IMyService>().GetData();
protected virtual void ConfigureServices(IServiceCollection services)
services.AddMyService();
// etc.
private IServiceProvider BuildServiceProvider()
var services = new ServiceCollection();
ConfigureServices(services);
return services.BuildServiceProvider();
但这可能并不总是合适的,所以我也会考虑直接设置值(虽然我没有找到任何关于这种方法有多好的官方信息)
public class Startup
public void Configure(IApplicationBuilder app)
...
app.SetupMyConfiguration();
...
...
public static class ApplicationBuilderExtensions
public static IApplicationBuilder SetupMyConfiguration(this IApplicationBuilder app)
var configuration = app
.ApplicationServices
.GetRequiredService<IConfiguration>(); // alternatively IOptions<MyOptions>
var myService = app
.ApplicationServices
.GetRequiredService<IMyService>();
configuration["MyKey"] = myService.GetData("MyKey");
【讨论】:
以上是关于具有其他依赖项的 ConfigurationProvider的主要内容,如果未能解决你的问题,请参考以下文章
具有依赖项的 Maven2 + JMeter + JUnit