Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从ServiceCollection获取IConfiguration_C#_Asp.net Core_Asp.net Core 2.0_Asp.net Core Configuration - Fatal编程技术网

C# 从ServiceCollection获取IConfiguration

C# 从ServiceCollection获取IConfiguration,c#,asp.net-core,asp.net-core-2.0,asp.net-core-configuration,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.FirstOrDef

我正在为
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"));
}
公共静态IServiceCollection AddApi(此IServiceCollection服务)
{
//从集合中获取配置
var configuration=(IConfiguration)services.FirstOrDefault(p=>p.ServiceType==typeof(IConfiguration)).ImplementationInstance;
services.Configure(configuration.GetSection(“数据库”));
}
这是从集合中获取
IConfiguration
实例的正确方法,还是有更优雅的解决方案?我不想将IConfiguration实例作为参数添加到方法中。

我创建了自己的“服务集合”类型,它包装了
IServiceCollection
IConfiguration
,我的所有模块都使用该类型注册它们的服务。例如:

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
实例,您可能会发现在服务集合中反复搜索它有点乏味。

根据注释,我已将扩展方法更改为:,因此,由应用程序的编写者为我的选项提供配置部分

public static IServiceCollection AddApi(this IServiceCollection services, IConfiguration databaseConfiguration)
{  
  services.Configure<DatabaseOptions>(databaseConfiguration);
}
以这种方式使用它的决定主要取决于这些评论。在开发许多开发人员使用的组件时,这种方式可能比在应用程序中使用的内部组件更相关


我觉得从任何地方访问IConfiguration都是一个糟糕的设计,除了 在组合根目录(ASP.NET核心的启动类)中,如下所示 表示配置文件必须具有特定的结构 这是根本无法改变的。相反,我将编写一个扩展方法 在组合根目录中配置配置类并传递 IConfiguration对象,类似于 .Configure(Configuration.GetSection(“MyLibConfi‌​g”)。 这样,开发人员就可以从您的 组件可以决定在appsettings.json中放置它的位置


或者,当两个库直接连接时,您将如何解决冲突 参考IConfiguration,并在 配置?即JsonSettings,但具有完全不同的结构?它 只有让编写它的开发人员选择 将节名称传递给设置 选项通过。配置


要从
IServiceCollection
获取
IConfiguration
,为什么不直接解析依赖项

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

显式依赖项应该直接注入到需要的地方。否则会使代码产生误导。尽管如此,正如前面所说的,如果直接将其注入到方法中会更好。我认为,从组合根内部以外的任何地方访问
IConfiguration
是一种糟糕的设计(
Startup
class for ASP.NET core),因为这意味着配置文件必须具有一个根本无法更改的特定结构。相反,我将编写一个扩展方法来配置composition根目录中的配置类,并将一个
IConfiguration
对象传递给,类似于
.configure(Configuration.GetSection(“MyLibConfig”)
。这样,当两个库直接引用
IConfiguration
并在配置中具有相同的部分时(即
JsonSettings
但具有完全不同的配置),使用组件编写应用程序的开发人员可以决定将其放置在appsettings.json中的位置,或者如何解决冲突Structure?只有让编写它的开发人员选择并将节名传递给通过
设置选项的your扩展方法才能解决此问题。配置
对我不起作用,因为
实现实例
为空。必须调用
实现工厂(空)
。可以工作,但当然相当脏。因为这需要构建服务提供商。取决于应用程序的类型和您正在执行的操作,这可能没有什么大不了的。
public void ConfigureServices(IServiceCollection services)
{
  services.AddApi(Configuration.GetSection("Database"));
  services.AddMvc();
}