我有一个用 C# 编写的 ASP.NET Core 7 MVC 应用程序。我想建立一个自定义
IConfiguration
以添加到已注册的提供者中。
我想使用DI服务集合中注册的一些服务来实现一些配置提供者。这些服务通常会从
IConfiguration
提供者那里获取价值。
我想使用使用现有
IConfiguration
提供者的信息配置的服务来引导新的 IConfiguration
,然后我想使用新的 IConfiguration
提供者来配置我想添加到服务集合中的更多服务。
我可能想添加一个基于存储库的
IConfiguration
,它需要一个连接字符串到存储库,例如,我可能想在存储库中保留其他服务的设置。存储库需要一些访问服务,也许是 EF。
天真地我可以尝试实例化一个“临时”服务提供者,使用临时服务构建配置提供者,将其添加到已注册的配置中,然后添加更多服务。这对我来说似乎不是一个好主意,特别是如果我有单例和作用域服务。
有没有办法真正使用服务提供者,然后添加更多服务,然后再次使用它?还是我疯了?
是的,您可以使用服务提供者配置一个 IConfiguration 实例,然后使用该实例配置更多服务以添加到服务集合中。您可以使用以下步骤实现此目的:
public class RepositoryConfigurationSource : IConfigurationSource
{
private readonly IRepositoryAccessService _repositoryAccessService;
public RepositoryConfigurationSource(IRepositoryAccessService repositoryAccessService)
{
_repositoryAccessService = repositoryAccessService;
}
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
var data = _repositoryAccessService.GetConfigurationData();
return new MemoryConfigurationProvider(new MemoryConfigurationSource
{
InitialData = data
});
}
}
public void ConfigureServices(IServiceCollection services)
{
// Register other services...
// Register the repository access service and the custom IConfigurationSource
services.AddSingleton<IRepositoryAccessService, MyRepositoryAccessService>();
services.AddConfiguration(config =>
{
config.Add(new RepositoryConfigurationSource(services.BuildServiceProvider().GetRequiredService<IRepositoryAccessService>()));
});
// Add more services that depend on the configuration data...
}
public class MyService : IMyService
{
public MyService(IConfiguration configuration)
{
// Use configuration data to configure the service
}
}
public void ConfigureServices(IServiceCollection services)
{
// Register other services...
// Register the repository access service and the custom IConfigurationSource
services.AddSingleton<IRepositoryAccessService, MyRepositoryAccessService>();
services.AddConfiguration(config =>
{
config.Add(new RepositoryConfigurationSource(services.BuildServiceProvider().GetRequiredService<IRepositoryAccessService>()));
});
// Add more services that depend on the configuration data...
services.AddSingleton<IMyService, MyService>();
}
请注意,在此示例中,我们创建了一个临时的 ServiceProvider 实例,以便检索 IRepositoryAccessService 实例以传递给 RepositoryConfigurationSource 构造函数。这是必要的,因为我们不能直接将服务注入 IConfigurationSource 实例,但这确实意味着 IRepositoryAccessService 实例将在释放临时 ServiceProvider 时被释放。如果您需要在应用程序的生命周期内保持服务实例处于活动状态,您可以将其注册为单例,而不是从临时 ServiceProvider 中检索它。