首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当T是类型时,用IOptions<T>配置ServiceCollection

当T是类型时,用IOptions<T>配置ServiceCollection
EN

Stack Overflow用户
提问于 2020-11-01 13:21:20
回答 2查看 1.2K关注 0票数 1

我需要用一个IOptions<T>注册一个.NET核心ServiceCollection

通常,这种方法如下所示:

代码语言:javascript
运行
复制
var configSection = configuration.GetSection("sectionName");
serviceCollection.Configure<KnownClassName>(configSection);

这将向容器注册强类型的IOptions<KnownClassName>

我需要注册一个IOptions<UnknownName>。我有这个班的Type。我似乎找不到允许我注册Type和配置部分的方法。

这就是我想要做的:

代码语言:javascript
运行
复制
interface ILoggingProvider
{
    Type GetSettingType();
    string ProviderName {get;}
}

IList<ILoggingProvider> loggingProviders = GetLoggingProviders();

foreach(var provider in loggingProvider)
{
    var providerSection = configuration.GetSection(providerSection);
    var providerSettingType = provider.GetSettingType();

    // can't find an overload or other method to do the same thing as 
    // serviceCollection.Configure<LoggerSettings>(providerSection);

    serviceCollection.Configure(providerSection, providerSettingType);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-01 14:25:53

我认为这是不可能的;检查the source of IServiceCollection.Configure显示,整个选项/配置功能都是围绕泛型类型构建的。

而且,据我所知,没有非通用的IOptions接口,因此没有真正的理由提供一个非通用的配置注册方法。

但是,这意味着您的ILoggingProvider实例必须使用IOptions<UnknownName>本身,否则它们将无法从DI容器中检索配置。在这种情况下,您可以公开特定提供者的options类,或者添加一个(Extension-)方法ILoggingProvider.RegisterOptions(IServiceCollection, IConfiguration),它自己完成这个注册。

在Startup.cs中,您可以简单地调用

代码语言:javascript
运行
复制
provider.RegisterOptions(serviceCollection, providerSection);

为每一个提供者。

当然,这需要对ILoggingProvider实现的源代码进行写访问。

票数 1
EN

Stack Overflow用户

发布于 2020-11-01 14:58:42

如果可以从services.ConfigureOptions返回实现IConfigureOptions<T>的类型,则可以使用ILoggingProvider.GetSettingType()

代码语言:javascript
运行
复制
public class CustomConfiguration
{
    public string Data { get; set; }
}

public class CustomConfigurationOptions : IConfigureOptions<CustomConfiguration>
{
    private readonly IConfiguration configuration;

    public CustomConfigurationOptions(IConfiguration configuration)
    {
        this.configuration = configuration;
    }

    public void Configure(CustomConfiguration options)
    {
        var optionsFromConfig = configuration
            .GetSection(nameof(CustomConfiguration))
            .Get<CustomConfiguration>();

        options.Data = optionsFromConfig.Data;
    }
}

public class LoggingProvider
{
    public Type Type { get; set; }
}

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        var loggingProviders = new List<LoggingProvider>()
        {
            new LoggingProvider()
            {
                Type = typeof(CustomConfigurationOptions)
            }
        };

        foreach (var loggingProvider in loggingProviders)
        {
            services.ConfigureOptions(loggingProvider.Type);
        }
    }
...
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64632368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档