DOTNET CORE源码分析之IOC容器结果获取内容补充

  补充一下ServiceProvider的内容

  可能上一篇文章DOTNET CORE源码分析之IServiceProvider、ServiceProvider、IServiceProviderEngine、ServiceProviderEngine和ServiceProviderEngineScope 中还没有关联上ServiceProvider和ServiceCollection就直接通过GetService获取了值,这样不科学啊。其实是有关联的,请看一下上篇文章同样存在的一个代码段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
internal ServiceProvider(
  IEnumerable<ServiceDescriptor> serviceDescriptors,
  ServiceProviderOptions options)
{
  IServiceProviderEngineCallback callback = (IServiceProviderEngineCallback) null;
  if (options.ValidateScopes)
  {
    callback = (IServiceProviderEngineCallback) this;
    this._callSiteValidator = new CallSiteValidator();
  }
  switch (options.Mode)
  {
    case ServiceProviderMode.Dynamic:
      this._engine = (IServiceProviderEngine) new DynamicServiceProviderEngine(serviceDescriptors, callback);
      break;
    case ServiceProviderMode.Runtime:
      this._engine = (IServiceProviderEngine) new RuntimeServiceProviderEngine(serviceDescriptors, callback);
      break;
    case ServiceProviderMode.Expressions:
      this._engine = (IServiceProviderEngine) new ExpressionsServiceProviderEngine(serviceDescriptors, callback);
      break;
    case ServiceProviderMode.ILEmit:
      this._engine = (IServiceProviderEngine) new ILEmitServiceProviderEngine(serviceDescriptors, callback);
      break;
    default:
      throw new NotSupportedException("Mode");
  }
}

  是的在这个构造函数中第一个参数:IEnumerable<ServiceDescriptor> serviceDescriptors,这个就是ServiceCollection的对应参数,这样,保存了用户添加的注入信息就和ServiceProviderEngine关联上了,然后ServiceProviderEngine可以为调用方提供数据,换句话说,ServiceProvider不是直接提供数据响应,而是借用ServiceProviderEngine的子类来提供,并且提供了ServiceProviderMode中提供的几种方式。

  我们再看看ServiceProviderMode的构造函数,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
protected ServiceProviderEngine(
  IEnumerable<ServiceDescriptor> serviceDescriptors,
  IServiceProviderEngineCallback callback)
{
  this._createServiceAccessor = new Func<Type, Func<ServiceProviderEngineScope, object>>(this.CreateServiceAccessor);
  this._callback = callback;
  this.Root = new ServiceProviderEngineScope(this);
  this.RuntimeResolver = new CallSiteRuntimeResolver();
  this.CallSiteFactory = new CallSiteFactory(serviceDescriptors);
  this.CallSiteFactory.Add(typeof (IServiceProvider), (IServiceCallSite) new ServiceProviderCallSite());
  this.CallSiteFactory.Add(typeof (IServiceScopeFactory), (IServiceCallSite) new ServiceScopeFactoryCallSite());
  this.RealizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>();
}

  这个过程做了很多初始化,我们把关注点集中在这一句:this.CallSiteFactory = new CallSiteFactory(serviceDescriptors),这句把ServiceCollection传递给了CallSiteFactory。CallSiteFactory是创建ServiceCallSite的工厂,具体作用下如下代码中:

1
2
3
4
5
6
7
8
9
private Func<ServiceProviderEngineScope, object> CreateServiceAccessor(
  Type serviceType)
{
  IServiceCallSite callSite = this.CallSiteFactory.CreateCallSite(serviceType, new CallSiteChain());
  if (callSite == null)
    return (Func<ServiceProviderEngineScope, object>) (_ => (object) null);
  this._callback?.OnCreate(callSite);
  return this.RealizeService(callSite);
}

  这里的IServiceCallSite callSite = this.CallSiteFactory.CreateCallSite(serviceType, new CallSiteChain()) 函数CreateCallSite实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
internal IServiceCallSite CreateCallSite(
      Type serviceType,
      CallSiteChain callSiteChain)
{
  lock (this._callSiteCache)
  {
    IServiceCallSite serviceCallSite1;
    if (this._callSiteCache.TryGetValue(serviceType, out serviceCallSite1))
      return serviceCallSite1;
    IServiceCallSite serviceCallSite2;
    try
    {
      callSiteChain.CheckCircularDependency(serviceType);
      serviceCallSite2 = this.TryCreateExact(serviceType, callSiteChain) ?? this.TryCreateOpenGeneric(serviceType, callSiteChain) ?? this.TryCreateEnumerable(serviceType, callSiteChain);
    }
    finally
    {
      callSiteChain.Remove(serviceType);
    }
    this._callSiteCache[serviceType] = serviceCallSite2;
    return serviceCallSite2;
  }
}

  其中this.TryCreateExact(serviceType, callSiteChain) ?? this.TryCreateOpenGeneric(serviceType, callSiteChain) ?? this.TryCreateEnumerable(serviceType, callSiteChain) 这个返回值是带有结果的ServiceCallSite,然后通过这个ServiceCallSite获取最终结果。

  接着介绍昨天没完成的内容

  昨天介绍到这个获取服务的函数,如下:

1
2
3
4
5
6
7
8
9
10
11
protected override Func<ServiceProviderEngineScope, object> RealizeService(
  IServiceCallSite callSite)
{
  int callCount = 0;
  return (Func<ServiceProviderEngineScope, object>) (scope =>
  {
    if (Interlocked.Increment(ref callCount) == 2)
      Task.Run<Func<ServiceProviderEngineScope, object>>((Func<Func<ServiceProviderEngineScope, object>>) (() => base.RealizeService(callSite)));
    return this.RuntimeResolver.Resolve(callSite, scope);
  });
}

  关注点停留在this.RuntimeResolver.Resolve(callSite, scope),这个函数在调用过程的时候带有两个参数callSite和scope,callSite就是刚刚介绍的ServiceCallSite,Scope是ServiceProviderEngineScope。RuntimeResolver是CallSiteRuntimeResolver的实例,Resolve方法如下:

 

1
2
3
4
public object Resolve(IServiceCallSite callSite, ServiceProviderEngineScope scope)
{
  return this.VisitCallSite(callSite, scope);
}

 

  其中VisitCallSite就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
protected virtual TResult VisitCallSite(IServiceCallSite callSite, TArgument argument)
{
  switch (callSite.Kind)
  {
    case CallSiteKind.Factory:
      return this.VisitFactory((FactoryCallSite) callSite, argument);
    case CallSiteKind.Constructor:
      return this.VisitConstructor((ConstructorCallSite) callSite, argument);
    case CallSiteKind.Constant:
      return this.VisitConstant((ConstantCallSite) callSite, argument);
    case CallSiteKind.IEnumerable:
      return this.VisitIEnumerable((IEnumerableCallSite) callSite, argument);
    case CallSiteKind.ServiceProvider:
      return this.VisitServiceProvider((ServiceProviderCallSite) callSite, argument);
    case CallSiteKind.Scope:
      return this.VisitScoped((ScopedCallSite) callSite, argument);
    case CallSiteKind.Transient:
      return this.VisitTransient((TransientCallSite) callSite, argument);
    case CallSiteKind.CreateInstance:
      return this.VisitCreateInstance((CreateInstanceCallSite) callSite, argument);
    case CallSiteKind.ServiceScopeFactory:
      return this.VisitServiceScopeFactory((ServiceScopeFactoryCallSite) callSite, argument);
    case CallSiteKind.Singleton:
      return this.VisitSingleton((SingletonCallSite) callSite, argument);
    default:
      throw new NotSupportedException(string.Format("Call site type {0} is not supported", (object) callSite.GetType()));
  }
}

  然后:

1
2
3
4
5
6
protected override object VisitConstant(
      ConstantCallSite constantCallSite,
      ServiceProviderEngineScope scope)
{
    return constantCallSite.DefaultValue;
}

  这个constantCallSite.Defaultvalue就是需要的返回结果了。

   上述的源码过程解析如下代码:

1
2
3
4
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton(typeof(string), "lizizhang");
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
string name = (string)serviceProvider.GetService(typeof(string));

  如果错误之处,请及时指正!

posted @   李志章  阅读(371)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示