从ServiceCollection获取IConfiguration

时间:2017-08-18 07:34:24

标签: c# asp.net-core asp.net-core-2.0 asp.net-core-configuration

我正在为ServiceCollection编写自己的扩展方法来注册我的模块类型,我需要从集合中访问IConfiguration实例来注册我的选项。

扩展方法

public static IServiceCollection AddApi(this IServiceCollection services)
{
  // Get configuration from collection
  var configuration = (IConfiguration) services.FirstOrDefault(p => p.ServiceType == typeof(IConfiguration)).ImplementationInstance;

  services.Configure<DatabaseOptions>(configuration.GetSection("Database"));
}

这是从集合中获取IConfiguration实例的正确方法还是有更优雅的解决方案?我不想将IConfiguration实例作为参数添加到方法中。

3 个答案:

答案 0 :(得分:4)

要从IConfiguration获得IServiceCollection,为什么不解决依赖关系呢?:

IConfiguration configuration = services.BuildServiceProvider().GetService<IConfiguration>();

答案 1 :(得分:2)

我创建了自己的&#34;服务集合&#34;包含IServiceCollectionIConfiguration的类型,我的所有模块都使用该类型来注册其服务。例如:

public interface IMyServiceCollection
{
    public IServiceCollection Services { get; set; }

    public IConfiguration Configuration { get; set; }
}

public static void AddFooModule(this IMyServiceCollection myServices)
{
    var services = myServices.Services;
    var config = myServices.Configuration;
}

然后,您必须使用配置实例作为参数创建扩展方法,该方法为IMyServiceCollection创建实现,例如:

public static IMyServiceCollection CreateServiceCollection(this IServiceCollection services, IConfiguration config)
{
    return new MyServiceCollection 
    { 
        Services = services,
        Configuration = config
    };
}

请注意,我们在模块化框架中使用它。对于简单的应用程序,这是过度的。

我认为您的解决方案也很好。但是,如果您需要经常访问IConfiguration实例,您可能会发现在服务集合中搜索它一遍又一遍有点乏味。

答案 2 :(得分:1)

根据评论,我已将扩展方法更改为以下内容,因此应用程序的编写者可以为我的选项提供配置部分。

public static IServiceCollection AddApi(this IServiceCollection services, IConfiguration databaseConfiguration)
{  
  services.Configure<DatabaseOptions>(databaseConfiguration);
}
来自StartUp类的

调用看起来像

public void ConfigureServices(IServiceCollection services)
{
  services.AddApi(Configuration.GetSection("Database"));
  services.AddMvc();
}

以这种方式使用它的决定主要是通过这些评论。在开发许多开发人员使用的组件时,这种方式可能更相关,而不是您在应用程序中使用的内部组件。

  

Imho从外面的任何地方访问IConfiguration是一个糟糕的设计   在组合根目录(ASP.NET核心的启动类)中,就像这样   意味着配置文件必须具有特定的结构   根本无法改变。相反,我会写一个扩展方法   在组合根目录中配置配置类并传递一个   IConfiguration对象,类似于如何   .Configure(Configuration.GetSection( “MyLibConfi克”)。   这样开发人员就可以从你的应用程序编写他的应用程序   组件可以决定将它放在appsettings.json

中的位置      

或者当你直接使用两个库时,你将如何解决冲突?   引用IConfiguration并在其中包含相同的部分   配置?即JsonSettings但结构完全不同?它   只能通过让构成它的开发者选择和解决   将节名称传递给您设置的扩展方法   选项通过.Configure