该
IServiceCollection接口用于
构建 依赖项注入容器。完全构建后,它将组成一个
IServiceProvider实例,您可以使用该实例来解析服务。您可以将注入
IServiceProvider到任何类中。的
IApplicationBuilder和
HttpContext类可以提供所述服务提供商以及经由其
ApplicationServices或
RequestServices分别性质。
IServiceProvider定义一种
GetService(Type type)解决服务的方法:
var service = (IFooService)serviceProvider.GetService(typeof(IFooService));
还有一些便利的扩展方法可用,如
serviceProvider.GetService<IFooService>()(添加
using的
Microsoft.Extensions.DependencyInjection)。
在启动类中解析服务
注入依赖
运行时的托管服务提供程序可以将某些服务注入到
Startup类的构造函数中,例如
IConfiguration,
IWebHostEnvironment(
IHostingEnvironment在3.0之前的版本中)
ILoggerFactory和
IServiceProvider。请注意,后者是由托管层构建的实例,并且
仅包含用于启动应用程序的基本服务 。
该
ConfigureServices()方法不允许注入服务,它仅接受一个
IServiceCollection参数。这是有道理的,因为
ConfigureServices()您可以在其中注册应用程序所需的服务。但是,您可以在此处使用注入到启动程序构造函数中的服务,例如:
public Startup(IConfiguration configuration){ Configuration = configuration;}public IConfiguration Configuration { get; }public void ConfigureServices(IServiceCollection services){ // Use Configuration here}ConfigureServices()然后,可以将注册的所有服务注入该
Configure()方法;您可以在
IApplicationBuilder参数后添加任意数量的服务:
public void ConfigureServices(IServiceCollection services){ services.AddScoped<IFooService>();}public void Configure(IApplicationBuilder app, IFooService fooService){ fooService.Bar();}手动解决依赖关系
如果您需要手动解决服务,你最好使用
ApplicationServices提供了通过
IApplicationBuilder在
Configure()方法:
public void Configure(IApplicationBuilder app){ var serviceProvider = app.ApplicationServices; var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();}可以
IServiceProvider在
Startup类的构造函数中直接传递in ,但是如上所述, 这将包含services的有限子集
,因此实用程序也受到限制:
public Startup(IServiceProvider serviceProvider){ var hostingEnv = serviceProvider.GetService<IWebHostEnvironment>();}如果必须使用该
ConfigureServices()方法解析服务,则需要使用其他方法。你可以建立一个中间
IServiceProvider从
IServiceCollection其中包含已注册的服务实例
到这一点 :
public void ConfigureServices(IServiceCollection services){ services.AddSingleton<IFooService, FooService>(); // Build the intermediate service provider var sp = services.BuildServiceProvider(); // This will succeed. var fooService = sp.GetService<IFooService>(); // This will fail (return null), as IBarService hasn't been registered yet. var barService = sp.GetService<IBarService>();}请注意: 通常,您应该避免在
ConfigureServices()方法内部解析服务,因为实际上这是您 配置
应用程序服务的地方。有时您只需要访问一个
IOptions<MyOptions>实例。您可以通过将
IConfiguration实例中的值绑定到的实例来实现此目的
MyOptions(本质上是选项框架所做的事情):
public void ConfigureServices(IServiceCollection services){ var myOptions = new MyOptions(); Configuration.GetSection("SomeSection").Bind(myOptions);}手动解决服务(又称为服务定位器)通常被认为是反模式。尽管有其用例(用于框架和/或基础结构层),但应尽可能避免使用它。



