.net core IOC容器实现(二) -- GetService

这篇具有很好参考价值的文章主要介绍了.net core IOC容器实现(二) -- GetService。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用IOC容器最重要的两个步骤就是注入服务和从容器内获取服务实例。上一节聊的ServiceDescriptor其实就可以看成注入服务的步骤,这一节初步聊一聊获取服务实例的相关源码。

  1. GetService
    GetService 方法是获取服务实例的入口,位于 ServiceProvider 这个类中
public object? GetService(Type serviceType) => GetService(serviceType, Root);

internal object? GetService(Type serviceType,
ServiceProviderEngineScope serviceProviderEngineScope)
{
    ...
    //如果有 realizedService 里有 ,获取,没有 就添加(serviceType 为key)  GetOrAdd(key,valueFactory) 根据key生成value
    Func<ServiceProviderEngineScope, object?> realizedService =
            _realizedServices.GetOrAdd(serviceType, _createServiceAccessor);
    //检验能否解析
    ....
    //获取服务实例  此处的核心 是 CallSiteRuntimeResolver 类(负责根据 scope 进行服务解析)
    var result = realizedService.Invoke(serviceProviderEngineScope);
    ...
    return result;
}

从上面的代码可以看出,主要经历了两步,第一步根据 _createServiceAccessor 获取一个泛型委托,第二步使用泛型委托生成服务实例。

  1. _createServiceAccssor
    _createServiceAccssor 是获取
// 定义
private readonly Func<Type, Func<ServiceProviderEngineScope, object?>> _createServiceAccessor;
//初始化是在 ServiceProvider 的构造函数中
_createServiceAccessor = CreateServiceAccessor;
// CreateServiceAccessor 方法
private Func<ServiceProviderEngineScope, object?> CreateServiceAccessor(Type serviceType)
{
      //通过 服务类型 获取 callSite,CallSite 包含了如何生成服务实例的相关信息, 比如服务实例的生命周期
      ServiceCallSite? callSite = CallSiteFactory.GetCallSite(serviceType, new CallSiteChain());
      if (callSite != null)
      {
              ...
               // Optimize singleton case  针对单例的优化
               if (callSite.Cache.Location == CallSiteResultCacheLocation.Root)
               {
                   //直接解析,如果callSite 里有,就直接返回 callSite 里存的值
                   object? value = CallSiteRuntimeResolver.Instance.Resolve(callSite, Root);
                   //以委托形式存下来
                   return scope => value;
               }
               //生成一个 可以通过 callSite 生成实例的委托
               return _engine.RealizeService(callSite);
        }
        return _ => null;
}

// 返回一个委托  Func<ServiceProviderEngineScope, object?>
// 该委托用途是生成 callSite 对应的servieType实例
public override Func<ServiceProviderEngineScope, object?> RealizeService(ServiceCallSite callSite)
{
  int callCount = 0;
  return scope =>
  {
     var result = CallSiteRuntimeResolver.Instance.Resolve(callSite, scope);
  }
}

首先通过CallSiteFactory获取一个一个callSite(在CallSiteFactory类中),可以先记住callSite作用是缓存和生成服务实例的细节,比如服务之间的依赖关系,如何创建实例的依赖。接下来则是根据服务的作用于范围,对单例做了优化,主要就是加了缓存(这个也是由callSite实现的),不用每次都去解析一次。如果不是单例,就需要结合callSite和_engine(scope相关)来获取服务了。但是从代码可以看出来无论是 Singleton 还是其他生命周期,最终调用的还是CallSiteRuntimeResolver.Instance.Resolve这个方法。

public object? Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
{
  // Fast path to avoid virtual calls if we already have the cached value in the root scope
  // 如果在 root scope 范围里已经有缓存了,直接返回,也就是对单例的优化,缓存
  if (scope.IsRootScope && callSite.Value is object cached)
  {
    return cached;
  }
  //调用 VisitCallSite 进行解析
  return VisitCallSite(callSite, new RuntimeResolverContext
  {
    Scope = scope
  });
}

因为对单例做了缓存,所以如果已经解析过了,就会直接返回缓存里的值,否则就调用VisitCallSite进行解析。

VisitCallSite 这个方法打算放到下节,对这部分感兴趣的也可以自行先去看一看CallSiteRuntimeResolver这个类。

  1. 根据泛型委托生成服务实例,这个就是简单的调用委托
var result = realizedService.Invoke(serviceProviderEngineScope);

以上就是本节的所有内容了,如有错误,请多指教。

======================================

补充文章来源地址https://www.toymoban.com/news/detail-494279.html

  • ServiceCallSite, 可以看到里面有一个 Value,那个就是缓存的单例的值
internal abstract class ServiceCallSite
 {
     // 构建方式  实例,工厂,构造器
     public abstract CallSiteKind Kind { get; }
     //生命周期 和 cacheKey
     public ResultCache Cache { get; }
     //Singleton存放点
      public object? Value { get; set; }
 }

到了这里,关于.net core IOC容器实现(二) -- GetService的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深入了解.net core的内置IOC容器 core

     嘿嘿! 如何理解IOC呢?我们可以通过一个现实世界的模型来进行解释。比如有 一本菜谱 这个 菜谱就是我们的IServiceCollection ,里面记录了 菜(Service) 的 描述信息(ServiceDescriptor)菜名(ServiceDescriptor.ServiceType) 以及菜 具体制作方法 (ServiceDescriptor.ImplementationType),通过

    2024年02月12日
    浏览(37)
  • asp.net core6 webapi 使用反射批量注入接口层和实现接口层的接口的类到ioc中

    IBLL接口层类库 BLL实现接口层类库 program中利用反射批量注入 在控制器中使用构造函数传参就可以调用已经注册的所有是是实现接口的类了的实列了

    2024年02月13日
    浏览(32)
  • 【.NET6+WPF】WPF使用prism框架+Unity IOC容器实现MVVM双向绑定和依赖注入

    前言:在C/S架构上,WPF无疑已经是“桌面一霸”了。在.NET生态环境中,很多小伙伴还在使用Winform开发C/S架构的桌面应用。但是WPF也有很多年的历史了,并且基于MVVM的开发模式,受到了很多开发者的喜爱。 并且随着工业化的进展,以及几年前微软对.NET平台的开源,国内大多

    2024年02月06日
    浏览(53)
  • .NET6.0实现IOC容器

    IOC 的作用这里省略…只对如何使用进行说明。 这里使用 .NET6.0 WebAPI 应用 下面是在 program 类中的代码 通过在 Controller 的构造函数中注入 IAuthService 启动后,通过 swagger 发起请求,验证接口。 基本 IOC容器 流程已实现。但是这样存在一个弊端,每个接口和实现都要在 program 中手

    2024年02月10日
    浏览(36)
  • .net下优秀的IOC容器框架Autofac的使用方法,实例解析

    Autofac是一个功能强大的依赖注入容器,它提供了一种简单和灵活的方式来管理对象之间的依赖关系。下面是Autofac的一些优点: 简单易用:Autofac提供了一种直观和简洁的方式来注册和解析依赖项。它的API设计得非常易于理解和使用,使得开发人员可以轻松地配置和管理依赖关

    2024年02月05日
    浏览(46)
  • .net core di ioc

    (Dependency Injection,DI)依赖注入,又称依赖关系注入,是一种软件设计模式,也是依赖倒置原则的一种体现。 依赖倒置原则的含义如下 上层模块不依赖下层模块。二者都依赖抽象 抽象不依赖细节 细节依赖抽象 依赖注入原则有别于传统的通过new直接依赖下层模块的形式,

    2024年02月22日
    浏览(30)
  • .NET 6和.Net Core学习笔记:.NET Core的重要问题

    什么是C#? .NET中主要的开发语言。 推荐C#书籍:《C#图解教程》,《C#入门经典》 尽管绝大部分用法都没变,但是.NET Core不是 .NET Framework的升级版,无法直接升级 绝大部分用法没有变,但又有部分是不能使用的。 又被微软坑了? .NET Framework白学了? 软件开发界的技术是不断

    2024年02月04日
    浏览(89)
  • .Net Core后端架构实战【3-介入IOC控制反转】

    摘要:基于.NET Core 7.0WebApi后端架构实战【2-介入IOC控制反转】  2023/04/09, ASP.NET Core 7.0, VS2022 Dependency Injection,何为依赖注入?由容器动态的将对象依赖的资源注入到对象之中。假设容器在构造对象A时,对象A的构造依赖对象B、对象C、对象D这些参数,容器会将这些依赖关系自

    2024年02月07日
    浏览(35)
  • .NET开源IOC内置容器,生命周期管理与Autofac扩展

    大家好,我是行不更名,坐不改姓的宋晓刚,下面将带领大家从基础小白到高阶的.NET的IOC容器依赖与注入,以及IOC内置容器和生命周期,Autofac的学习,跟上我的步伐进入C#的世界。 微信:15319589104 QQ: 2981345658 文章内容: .NET依赖注入容器的生命周期管理,瞬时生命周期(

    2024年01月21日
    浏览(41)
  • 如何在ASP.NET Core应用中实现与第三方IoC/DI框架的整合?

    我们知道整个ASP.NET Core建立在以ServiceCollection/ServiceProvider为核心的DI框架上,它甚至提供了扩展点使我们可以与第三方DI框架进行整合。对此比较了解的读者朋友应该很清楚,针对第三方DI框架的整合可以通过在定义Startup类型的ConfigureServices方法返回一个ServiceProvider来实现。但

    2024年02月09日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包