ApplicationServices(根)IServiceProvider和注入的IServiceProvider有什么区别? [英] What's the difference between the ApplicationServices (root) IServiceProvider and an injected IServiceProvider?

查看:899
本文介绍了ApplicationServices(根)IServiceProvider和注入的IServiceProvider有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解为什么使用 IApplicationBuilder.ApplicationServices 代替<$ c时在Startup Configure方法中应用服务定位器模式的行为有所不同的原因$ c> IServiceProvider 。



当我使用 IApplicationBuilder.ApplicationServices (其中设置 IServiceProvider 来提供对应用服务容器的访问权限),出现以下错误:


无法从根提供商解析作用域服务'...'


相反,当我直接使用注入 IServiceProvider 时,它就像一种魅力:

  public void Configure(
IApplicationBuilder应用程序,IWebHostEnvironment env,IServiceProvider sp)
{
// 1:直接从应用程序服务解析作用域服务container
// IServiceProvider抛出无法从根提供商的
解析作用域服务var test1 = app.ApplicationServices.GetRequiredService< IMyScopedService>();

// 2:就像一个魅力
var test2 = sp.GetRequiredService< IMyScopedService>();

// 3:也可以像超级按钮一样工作
var scope = app.ApplicationServices.CreateScope();
var test3 = scope.ServiceProvider.GetRequiredService< IMyScopedService>();
}

这是为什么?为什么注入的 IServiceProvider 表现为具有服务范围,而 IApplicationBuilder.ApplicationServices 则具有类似应用程序范围之外的服务范围?



以某种方式注入的 IServiceProvider 起作用与首先使用 IApplicationBuilder 创建作用域,然后再从作用域的服务提供者解析作用域服务相同。



我的头现在在旋转。



很明显, IApplicationBuilder 的范围(是否这样命名)在服务范围之外。但是当我查找 IApplicationBuilder 我找不到有关根提供程序的任何信息。



有人可以澄清吗?我错过了

解决方案

这是设计使然。

ASP.NET运行时实例化 IServiceProvider ,以使其禁止从根目录解析作用域服务:

  serviceCollection.BuildServiceProvider(validateScopes:true); 

app.ApplicationServices 是根 IServiceProvider sp app.ApplicationServices 的子级。您可以使用以下代码行进行检查:

  app.ApplicationServices ==((Microsoft Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)sp).Engine.Root 
// true

因此,只有 app.ApplicatoinServices 的子级才能解析作用域服务。提供了一个孩子 sp 作为输入参数,第二个是您手动创建的。


I have a hard time understanding why the behaviour is different to apply the service locator pattern in the Startup Configure method when using the IApplicationBuilder.ApplicationServices in stead of IServiceProvider.

When I use IApplicationBuilder.ApplicationServices (which sets the IServiceProvider that provides access to the application's service container) I get the following error:

Cannot resolve scoped service '...' from root provider

In contrast, when I use the injected IServiceProvider directly it works like a charm:

public void Configure(
    IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider sp)
{
  // 1 : resolving a scoped service directly from application services container
  // IServiceProvider throws 'Cannot resolve scoped service from root provider'
  var test1 = app.ApplicationServices.GetRequiredService<IMyScopedService>();

  // 2 : works like a charm 
  var test2 = sp.GetRequiredService<IMyScopedService>();

  // 3 : also works like a charm
  var scope = app.ApplicationServices.CreateScope();
  var test3 = scope.ServiceProvider.GetRequiredService<IMyScopedService>();
}

Why is this? Why does the injected IServiceProvider behave like it has "service scope" and IApplicationBuilder.ApplicationServices like it has a sort of "application scope" outside of service scopes?

In a way the injected IServiceProvider works the same as creating a scope first with IApplicationBuilder and only then resolving the scoped service from the scope's service provider.

My head is spinning now.

Obviously it seems that the scope of IApplicationBuilder (does one name it like this?) is outside of service scopes. But when I look up IApplicationBuilder I can't find anything about the root provider.

Can anyone clarify this? Did I miss an obvious beginners tutorial somewhere that explains this root provider or application's service container?

解决方案

This is by design.

ASP.NET runtime instantiate IServiceProvider in such way that it prohibits scoped services resolved from the root:

serviceCollection.BuildServiceProvider(validateScopes: true);

app.ApplicationServices is root IServiceProvider. sp is child of app.ApplicationServices. You can check it using this line of code:

app.ApplicationServices == ((Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)sp).Engine.Root
// true

So only children of app.ApplicatoinServices can resolve scoped services. One child sp was provided as input parameter, 2nd one you created manually.

这篇关于ApplicationServices(根)IServiceProvider和注入的IServiceProvider有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆