具体来说,在异步执行的操作中,我们利用调用上面注入的这个IServiceProvider对象的GetRequiredService方法试图获取一个IFoobar服务实例。...public class HomeController: Controller { private readonly IServiceProvider _requestServices;...二、ApplicationServices与RequestServices 从上图所示的错误消息可以看出,问题出在我们试图利用一个被Dispose的IServiceProvider来获取我们所需的服务实例...我们知道,ASP.NET Core应用在启动和请求处理过程中所需的服务几乎都是由代表DI容器的IServiceProvider提供的。...具体来说,这里存在着两种类型的IServiceProvider对象,一种与当前应用的生命周期保持一致,我们一般将其称为ApplicationServices,另一种则是具体针对每个请求的IServiceProvider
探索 .NET Core 依赖注入的 IServiceCollection[1] 在本文中,我们会学习 IServiceProvider,了解它是什么,以及它是怎么创建出来的,我们将根据上一篇文章中创建的...IServiceCollection来学习如何构建IServiceProvider。...什么是 IServiceProvider?...IServiceProvider会根据程序的要求在运行时解析服务类型的实例,ServiceProvider来保证已解析的服务在预期的生命周期内有效,这个实现设计的非常高效,所以服务的解析速度非常快。...构建一个 IServiceProvider 首先,当我们把服务都添加到 IServiceCollection ,接下来会构建一个IServiceProvider, 它能够提供我们程序中所依赖服务的实例,
IServiceProvider的这一特性体现在如下所示的调试断言中。...Scoped服务实例被保存在当前IServiceProvider上,所以它只能在当前IServiceProvider对象的“服务范围”保证的单例的。...属性返回一个新的IServiceProvider对象,它实际上是当前IServiceProvider对象的子容器。...图1 IServiceProvider按照服务注册对应的生命周期模式提供服务实例 作为DI容器的IServiceProvider不仅仅为我们提供所需的服务实例,它还帮我们管理者这些服务实例的生命周期。...这个实例充分说明了一旦开启了针对服务范围的验证,IServiceProvider对象不可能提供以单例形式存在的Scoped服务。 ? 图3 IServiceProvider针对服务范围的检验
当需要消费某个服务实例的时候,我们只需要指定服务类型调用IServiceProvider的GetService方法,IServiceProvider就会根据对应的服务注册提供所需的服务实例。...目录 一、IServiceProvider 二、构造函数的选择 三、服务范围 四、三种生命周期模式 五、ASP.NET Core应用下的生命周期 六、服务范围检验 一、IServiceProvider...图4从物理层面揭示了IServiceScope/IServiceProvider对象之间的关系,任何一个IServiceProvider对象都具有针对根容器的引用。 ?...就服务实例的提供方式来说,它们之间具有如下的差异: Singleton:IServiceProvider创建的服务实例保存在作为根容器的IServiceProvider上,所有多个同根的IServiceProvider...Scoped:IServiceProvider创建的服务实例由自己保存,所以同一个IServiceProvider对象提供的针对同一类型的服务实例均是同一个对象。
(), rootScope)); Debug.Assert(ReferenceEquals(child1.GetRequiredService<IServiceProvider...对于IServiceProvider对象的注入,有个细节大家可能忽略或者误解。...读者朋友们可以试着思考这么一个问题:如果我们在某个服务中注入了IServiceProvider对象,当我们利用某个IServiceProvider对象来提供该服务实例的时候,注入的IServiceProvider...; } } 我们最终利用一个作为子容器的IServiceProvider对象(ServiceProviderEngineScope对象)来提供这来个服务类型的实例,并通过调试断言确定注入的IServiceProvider...基于生命周期模式注入IServiceProvider对象的策略可以通过如下这个测试程序来验证。
如上图所示的树形层次结构只是一种逻辑结构,从对象引用层面来看,通过某个IServiceScope封装的IServiceProvider对象不需要知道自己的“父亲”是谁,它只关心作为根节点的IServiceProvider...下图从物理层面揭示了IServiceScope / IServiceProvider对象之间的关系,任何一个IServiceProvider对象都具有针对根容器的引用。 ?...就服务实例的提供方式来说,它们之间具有如下的差异: Singleton:IServiceProvider对象创建的服务实例保存在作为根容器的IServiceProvider对象上,所以多个同根的IServiceProvider...Scoped:IServiceProvider对象创建的服务实例由自己保存,所以同一个IServiceProvider对象提供的针对同一类型的服务实例均是同一个对象。...IServiceProvider对象针对服务实例采用的回收释放策略取决于采用的生命周期模式,具体策略主要体现为如下两点: Singleton:提供Disposable服务实例保存在作为根容器的IServiceProvider
具体来说,由于Singleton服务实例保存在作为根容器的IServiceProvider对象上,所以能够在多个同根IServiceProvider对象之间提供真正的单例保证。...IServiceProvider对象,实际上是当前IServiceProvider对象的子容器。...Transient和Scoped:所有实现了IDisposable接口的服务实例会被当前IServiceProvider对象保存起来,当IServiceProvider对象的Dispose方法被调用的时候...图2 服务实例的释放 [306]服务范围的验证 Singleton和Scoped这两种不同的生命周期是通过将提供的服务实例分别存放到作为根容器的IServiceProvider对象和当前IServiceProvider...图4 构建IServiceProvider对象针对服务注册有效性的检验
针对服务实例的提供还有这么一个细节:如果我们在调用GetService或者GetService方法时服务类型设置为IServiceProvider接口,提供的服务实例实际上就是当前的IServiceProvider...由于Singleton服务实例保存在作为根容器的IServiceProvider对象上,所以它能够在多个同根IServiceProvider对象之间提供真正的单例保证。...该对象的ServiceProvider属性返回一个新的IServiceProvider对象,它实际上是当前IServiceProvider对象的子容器。...我们最后利用作为子容器的IServiceProvider对象来提供相应的服务实例。...三、针对服务注册的验证 Singleton和Scoped这两种不同的生命周期是通过将提供的服务实例分别存放到作为根容器的IServiceProvider对象和当前IServiceProvider对象来实现的
当需要消费某个服务实例的时候,我们只需要指定服务类型调用IServiceProvider的GetService方法即可,IServiceProvider对象就会根据对应的服务注册提供所需的服务实例。...一、IServiceProvider 如下面的代码片段所示,IServiceProvider接口定义了唯一的GetService方法根据指定的类型来提供对应的服务实例。...public interface IServiceProvider { object GetService(Type serviceType); } 针对IServiceProvider对象的创建体现在...如果IServiceProvider对象试图通过调用构造函数的方式来创建服务实例,传入构造函数的所有参数必须先被初始化,所以最终被选择出来的构造函数必须具备一个基本的条件,那就是IServiceProvider...根据我们前面介绍的第一个原则(IServiceProvider对象能够提供构造函数的所有参数),Gux的前两个构造函数会成为合法的候选构造函数,那么IServiceProvider最终会选择哪一个呢?
IServiceCollection集合到IServiceProvider对象之间的适配问题。...一、IServiceCollection =>ContainerBuilder=>IServiceProvider 具体来说,我们可以在IServiceCollection集合和IServiceProvider...我们先利用包含原始服务注册的IServiceCollection集合来创建一个ContainerBuilder对象,再利用该对象来构建作为依赖注入容器的IServiceProvider对象。 ?...GetServices方法会利用这个IServiceProvider对象创建一个服务范围,并利用此服务范围内的IServiceProvider提供两组服务实例。...通过CatServiceProviderFactory创建的IServiceProvider对象在最终通过调用其Dispose方法进行释放。
对于绝大部分AOP框架来说,它们最终都会体现为创建一个能够拦截的“代理对象”来实现对方法调用的拦截,但是.NET Core中针对服务实例的提供完全由通过IServiceProvider接口表示的DI容器来接管...= _clock.GetType()); } } 二、让IServiceProvider直接代理对象 在被依赖类型的构造函数中注入IInterceptable服务的编程方式总显得有点别扭,...我们最终需要解决的还是如何让IServiceProvider直接提供可被拦截的代理对象,为此我对.NET Core依赖注入框架的源代码作了一点很小的改动。...这个经过简单修改的IServiceProvider实现类型就是如下这个InterceptableServiceProvider 类型。...public class Startup { public IServiceProvider ConfigureServices(IServiceCollection services)
通过《利用容器提供服务》我们知道作为依赖注入容器的IServiceProvider对象是通过调用IServiceCollection接口的扩展方法BuildServiceProvider创建的,IServiceCollection...一、IServiceCollection ServiceDescriptor是对某个服务注册项的描述,作为依赖注入容器的IServiceProvider对象正是利用该对象提供的描述信息才得以提供我们需要的服务实例...如果指定的是一个Func对象(对应于ImplementationFactory属性),那么该委托对象将作为提供服务实例的工厂。...这主要发生在提供的ServiceDescriptor对象是由服务实例工厂创建的情况,所以上面实例中用来创建ServiceDescriptor的工厂类型分别为Func和Func,而不是Func。
容器的核心 - IServiceProvider接口 ASP.NET Core依赖注入抽象的核心是IServiceProvider接口。该接口实际上是System命名空间中基类库的一部分。...当然,您通常根本不应该直接在代码中使用IServiceProvider。相反,您应该使用标准的构造函数注入,并让框架来承载并在幕后使用IServiceProvider。...直接使用IServiceProvider是服务定位器模式的一个示例。这通常被认为是反模式,因为它隐藏了类的依赖关系。 然而,有些时候你没有选择的余地。...例如,如果您试图将服务注入到属性,或者在配置DI容器时使用“转发”类型,则需要直接使用IServiceProvider。...摘要 GetService()是IServiceProvider上的唯一方法,ISeviceProvider是ASP.NET核心DI抽象中的中央接口。
包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IServiceProvider对象。...Cat中的服务注册是通过一个类型为ServiceRegistry的对象表示的,在IServiceCollection/IServiceProvider为核心的DI框架中,与之对应的类型为ServiceDescriptor...如果指定的是一个Func对象(对应于ImplementationFactory属性),那么IServiceProvider对象将会将自身作为输入参数调用该委托对象来提供服务实例...这种情况主要发生在提供的ServiceDescriptor对象是由服务实例工厂创建的情况,所以上面实例中用来创建ServiceDescriptor的工厂类型分别为Func和Func,而不是Func。
public interface IInterceptingProxyFactory { IServiceProvider ServiceProvider { get; } object...Wrap(Type typeToIntercept, object target); object Create(Type typeToIntercept, IServiceProvider...IInterceptingProxyFactory { public IInterceptorResolver InterceptorResolver { get; } public IServiceProvider...serviceProvider); public object Create(Type typeToIntercept, IServiceProvider serviceProvider...serviceProvider); protected override object Create(Type typeToIntercept, IServiceProvider serviceProvider
ASP.NET Core中的DI容器体现为一个实现了IServiceProvider接口的对象。...作为一个服务的提供者,ASP.NET Core中的DI容器最终体现为一个IServiceProvider接口,我们将所有实现了该接口的类型及其实例统称为ServiceProvider。...1: public interface IServiceProvider 2: { 3: object GetService(Type serviceType); 4: } ASP.NET...除此之外,服务的提供还可以通过IServiceProvider接口相应的扩展方法来完成。如下面的代码片段所示,扩展方法GetService以泛型参数的形式指定服务的声明类型。...除此之外, 我们可以直接调用IServiceProvider如下两个扩展方法GetServeces达到相同的目的。
public static IServiceScope CreateScope(this IServiceProvider provider) { return provider.GetRequiredService...GetRequiredService方法的最终实现: public static object GetRequiredService(this IServiceProvider provider, Type...serviceType) { provider.GetService(serviceType); } 由接口IServiceProvider的实现类来获取指定的服务。...internal interface IServiceProviderEngine : IDisposable, IServiceProvider { IServiceScope RootScope...该方法签名如下: internal class ServiceProviderEngineScope : IServiceScope, IServiceProvider { } 最后我们还是调用
GetServices()和GetRequiredService()方法,还实现了获取子容器方法CreateScope(),下面来具体的看一下这个类型 从下面代码看到ServiceProvider一个实现了三个接口 IServiceProvider...validateScopes时使用的,接口具有两个方法OnCreate()和OnResolve()分别用于创建服务实例时缓存和校验, public sealed class ServiceProvider : IServiceProvider...前面已经说过目前DI只使用了Dynamic这一种,下面说IServiceProviderEngineCallback时也只说这一种 public sealed class ServiceProvider : IServiceProvider...class ServiceProviderServiceExtensions { // 泛型重载 public static T GetService(this IServiceProvider...return (IEnumerable)provider.GetRequiredService(genericEnumerable); } // 创建一个子IServiceProvider
根ServiceProvider: WebHost类中的属性Services返回的ServiceProvider private IServiceProvider _applicationServices...; public IServiceProvider Services { get { return _applicationServices; } } 它的实例化是通过IServicesCollection...类负责创建非根ServiceProvider: private readonly IServiceScopeFactory _scopeFactory; // 或者 private readonly IServiceProvider...2、调用IServiceProvider接口的CreateScope随后调用ServiceProvider属性。该方法创建的是一个特定范围的ServiceProvider。...总结一下aspnet core获取注册服务的实例如下: IServiceProvider.CreateScope() IServiceProvider.GetRequestService<IServiceScopeFactory
领取专属 10元无门槛券
手把手带您无忧上云