我正在编写自己的扩展方法,用于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 实例作为参数添加到该方法中。
要从IServiceCollection
获取IConfiguration
,为什么不直接解决依赖关系?
IConfiguration configuration = services.BuildServiceProvider().GetService<IConfiguration>();
根据评论,我已将扩展方法更改为以下内容,以便由应用程序的作曲家为我的选项提供配置部分。
public static IServiceCollection AddApi(this IServiceCollection services, IConfiguration databaseConfiguration)
{
services.Configure<DatabaseOptions>(databaseConfiguration);
}
从启动类中,调用看起来像
public void ConfigureServices(IServiceCollection services)
{
services.AddApi(Configuration.GetSection("Database"));
services.AddMvc();
}
以这种方式使用它的决定主要是由这些评论决定的。在开发许多开发人员使用的组件时,这种方式可能比在应用程序中使用的内部组件更相关。 还有官方文档指南解释了相同的方法
恕我直言,从任何地方访问 IConfiguration 是一个糟糕的设计,除了 在组合根(ASP.NET 核心的启动类(中,如下所示 暗示配置文件必须具有特定的结构 根本无法改变。相反,我会编写一个扩展方法 在组合根目录中配置配置类并传递 图标对象,类似于如何 .Configure(Configuration.GetSection("MyLibConfi g"(. 这样,从您的应用程序编写应用程序的开发人员 组件可以决定将其放置在appsettings.json中的位置
或者当两个库直接时,您将如何解决冲突 参考 IConfigraphy,并在 配置?即Json设置,但结构完全不同?它 只能通过让编写它的开发人员选择和 将节名称传递给您的扩展方法,该方法设置 通过 的选项。配置
我创建了自己的"服务集合"类型,它包装了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
实例,您可能会发现在服务集合中反复搜索它有点乏味。
文档说你应该要求用户为你提供适当的 IConfigraphy:
public static IServiceCollection AddApi(this IServiceCollection services, IConfiguration configSection)
{
services.Configure<DatabaseOptions>(configSection);
// ...
return services;
}
您需要包Microsoft.Extensions.Options.ConfigurationExtensions
才能正常工作。