C# 配置IOptions<;T>;当T为类型时,使用ServiceCollection

C# 配置IOptions<;T>;当T为类型时,使用ServiceCollection,c#,asp.net-core,configuration,C#,Asp.net Core,Configuration,我需要向.NET CoreServiceCollection注册一个IOOptions 通常,方法如下所示: var configSection = configuration.GetSection("sectionName"); serviceCollection.Configure<KnownClassName>(configSection); 我认为这是不可能的;检查表明整个选项/配置功能是围绕泛型类型构建的 另外,据我所知,没有非通用的IOptions接

我需要向.NET Core
ServiceCollection
注册一个
IOOptions

通常,方法如下所示:

var configSection = configuration.GetSection("sectionName");
serviceCollection.Configure<KnownClassName>(configSection);

我认为这是不可能的;检查表明整个选项/配置功能是围绕泛型类型构建的

另外,据我所知,没有非通用的
IOptions
接口,因此没有理由提供非通用的配置注册方法


但是,这意味着您的
ILoggingProvider
实例必须使用
IOptions
本身,否则它们将无法从DI容器检索配置。在这种情况下,您可以公开特定提供程序的选项类,或者添加一个(扩展)方法
ilogingprovider.RegisterOptions(IServiceCollection,IConfiguration)
,该方法本身进行注册

在Startup.cs中,您只需调用

provider.RegisterOptions(serviceCollection, providerSection);
对于每个提供者


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

如果可以从
ilogingprovider.GetSettingType()返回实现
IConfigureOptions
的类型,则可以使用
服务.ConfigureOptions

公共类自定义配置
{
公共字符串数据{get;set;}
}
公共类CustomConfigurationOptions:IConfigureOptions
{
专用只读IConfiguration配置;
公共自定义配置选项(IConfiguration配置)
{
this.configuration=配置;
}
公共无效配置(自定义配置选项)
{
var options fromconfig=配置
.GetSection(名称(自定义配置))
.Get();
options.Data=optionsFromConfig.Data;
}
}
公共类日志提供程序
{
公共类型类型{get;set;}
}
公营创业
{
公共启动(IConfiguration配置)
{
配置=配置;
}
公共IConfiguration配置{get;}
//此方法由运行时调用。请使用此方法将服务添加到容器中。
public void配置服务(IServiceCollection服务)
{
services.AddControllers();
var loggingProviders=新列表()
{
新日志提供者()
{
类型=类型(CustomConfigurationOptions)
}
};
foreach(loggingProviders中的var loggingProvider)
{
services.ConfigureOptions(loggingProvider.Type);
}
}
...
}

这方面的问题是我不知道在基本记录器类中。这是一个泛型类型,这就是为什么我公开了GetSettingsType()方法。您不需要在基类中知道它,选项类型将从实现中返回。我考虑到这一点。事实上,如果找不到使用类型配置IOPS的方法,这是我剩下的两个选项之一。我的问题是关注点的分离(或缺乏关注点)。ILOGingProvider—更具体地说,GetProviderType()方法位于基类中。虽然这完成了任务,但我的基本LoggingProvider类现在提供了用于日志支持和服务注册的方法,这让我感到困扰。我将为每个派生提供者实现一个扩展方法;允许我调用serviceCollection.Configure(配置);
provider.RegisterOptions(serviceCollection, providerSection);
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);
        }
    }
...
}