依赖注入怎么理解_面试官的问题回答不上来怎么办

依赖注入怎么理解_面试官的问题回答不上来怎么办IOC: Inversion Of Control 控制反转DI: Dependency Injection 依赖注入1.控制反转 Invers

IOC: Inversion Of Control 控制反转

DI: Dependency Injection 依赖注入

依赖注入怎么理解_面试官的问题回答不上来怎么办

1.控制反转 Inversion Of Control 的前世今生

1.1 IOC理论产生的背景

讨论控制反转之前,先看看软件系统提出控制反转的前世今生。
一个完整精密的软件系统,组件之间就像齿轮,协同工作,相互耦合。

  • 一个零件不正常,整个系统就崩溃了。
  • 系统对象之间耦合关系无法避免,在项目规模和复杂度变大的情况下,管理类之间的依赖关系将会很复杂。
  • 对象之间耦合度很高的系统,架构师和开发人员对于系统的修改,必然会出现牵一发而动全身的情形。
  • 对象之间耦合性依赖,单元测试很复杂。

1.2 IOC理论

软件专家为此提出IOC理论,用来实现对象之间的解耦。
再来看看,控制反转(IOC)到底为什么要起这么个名字?我们来对比一下:

  1. 软件系统在没有引入IOC容器之前,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在自己手上。
  2. 软件系统在引入IOC容器之后,这种情形就完全改变了,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。

通过前后对比,我们不难看出:
对象A获得依赖对象B的过程,由主动变为了被动行为,控制权颠倒过来,这就是[控制反转]的由来

1.3 控制反转 和 依赖注入

有些人会把控制反转和依赖注入等同,实际上有本质区别:
控制反转是 一种思想;
依赖注入是一种设计模式。
依赖注入是实现控制反转的一种方式,但是控制反转还有其他实现方式,例如说ServiceLocator(服务定位器、依赖查找),所以不能将控制反转和依赖注入等同。

依赖注入怎么理解_面试官的问题回答不上来怎么办

2 依赖注入 Dependency Injection

依赖注入:容器全权负责组件的装配,它会把符合依赖关系的对象通过属性或者构造函数传递给需要的对象。

符合依赖倒置原:高层模块不应该依赖低层模块,两者都应该依赖抽象;抽象不应该依赖于细节,细节应该依赖于抽象。

2.1 ASP.NET Core依赖注入

使用方式大体类似:
①. 定义依赖实现的接口或者抽象类
②. 在服务容器中注册组件依赖 :IServiceProvider
③. 在构造函数中注入服务, 框架会负责创建和销毁实例

依赖注入怎么理解_面试官的问题回答不上来怎么办

// 编写组件和服务public interface IMyDependency{    string WriteMessage(string message);}---public class MyDependency : IMyDependency{    public string WriteMessage(string message)    {       return #34;MyDependency.WriteMessage Message: {message}";    }}// 注册组件和依赖,下面注册的`IMyDependency`在一个web请求中有效public void ConfigureServices(IServiceCollection services){    services.AddScoped<IMyDependency, MyDependency>();    services.AddRazorPages();}---// 在构造函数注入组件public class HomeController: AbpController{    private readonly IMyDependency _dep;    public HomeController(IMyDependency dep)    {       _dep = dep;    }  public IActionResult Index()  {    var content =  _dep.WriteMessage(#34;The Reflection instance is {_dep.GetType().FullName} ");    return Content(content);  }}

在请求某个服务时,框架会完整解析出这个对象的依赖树和作用范围。

上面的示例代码形成
req—>HomeController—>IMyDependency 依赖树
IMyDependency在每个web请求范围内使用同一服务实例。

输出:MyDependency.WriteMessage Message: The Reflection instance is TestDI.MyDependency

2.2 对象生命周期

根据现实需要,前人从使用场景中总结出三种服务生命周期。
ASP.NET Core提供了一个枚举ServiceLifetime

依赖注入怎么理解_面试官的问题回答不上来怎么办

对于Scoped Service的理解:

依赖注入怎么理解_面试官的问题回答不上来怎么办

在webapp:scoped service 会在请求结束时被销毁;
在EFCore: 使用AddDbContext默认也会注册特定范围的DbContext,这意味在我们可以在一次sql连接内,使用同一个DbContext实例进行多次DB操作。

2.3 依赖注入实现原理

结合理论、使用方式 猜测依赖注入的原理:
实现DI,核心在于依赖注入容器IContainer,该容器具有以下功能
①.(容器)保存可用服务的集合
// 要用的特定对象、特定类、接口服务

②.(注册)提供一种方式将各种部件与他们依赖的服务绑定到一起;
// Add…函数或containerBuilder.Register函数,

③.(解析点)为应用程序提供一种方式来请求已配置的对象: 构造函数注入、属性注入.

运行时,框架会一层层通过反射构造实例,最终得到完整对象。

3.源码导航

利用反射产生对象是依赖注入的核心过程,这也是面试造航母时经常问到的。

.NETSystem.ReflectionSystem.Type命名空间中的类可以获取可装配组件、类、接口的信息,并提供了在运行时创建实例,调用动态实例方法、获取动态实例的能力。

当我尝试从github源码中探究[依赖注入产生对象]的伪代码时,文件/代码众多,迷路了!

依赖注入怎么理解_面试官的问题回答不上来怎么办

实际上,我们可以在依赖树的尾部对象的构造函数手动抛出异常,异常的调用栈就是一个天然的源码导航。

于是我在上面示例代码的request—-> HomeController—>MyDependency
MyDependency构造函数中添加异常代码:

    public MyDependency()
    {
       throw new Exception("exception content!");
    }

结果如下图:

依赖注入怎么理解_面试官的问题回答不上来怎么办

从Github Dependency Injection 库进入System.Reflection的调用分界线代码:

protected override object VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
{
    object[] parameterValues;
    if (constructorCallSite.ParameterCallSites.Length == 0)
    {
         parameterValues = Array.Empty<object>();
    }
    else
    {
       parameterValues = new object[constructorCallSite.ParameterCallSites.Length];
       for (var index = 0; index < parameterValues.Length; index++)
      {
         parameterValues[index] = VisitCallSite(constructorCallSite.ParameterCallSites[index], context);
       }
    }

    try
    {
       return constructorCallSite.ConstructorInfo.Invoke(parameterValues);
    }
    catch (Exception ex) when (ex.InnerException != null)
    {
       ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
      // The above line will always throw, but the compiler requires we throw explicitly.
      throw;
     }
}

黄色背景行就是.NET反射特性的体现:
对类型信息(构造函数、参数)使用Invoke方法产生对象。

干货旁白

  1. 控制反转是一种在软件工程中解耦合的思想,调用方依赖接口或抽象类,减少了耦合,控制权交给了服务容器,由容器维护注册项,并将具体的实现动态注入到调用方。
  2. 有些人会把控制反转和依赖注入等同,实际上有本质区别:
    控制反转是 一种思想;
    依赖注入是一种设计模式。
    依赖注入是实现控制反转的一种方式,但是控制反转还有其他实现方式,例如说ServiceLocator,所以不能将控制反转和依赖注入等同。
  3. 在运行时,框架会解析依赖树、依赖图,通过反射在运行期生成对象。

作者:_小码甲

原文链接:https://www.cnblogs.com/JulianHuang/p/13836852

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/11851.html

(0)

相关推荐

  • 配置定时任务的 cron 表达式有哪几种?

    配置定时任务的 cron 表达式有哪几种?Cron 表达式是一种用于配置 Cron 任务调度的字符串格式,主要用于 Unix 和 Unix-like 系统的定时任务服务,以及一些其他的任务调度库和服务,如 Quartz、Spring、AWS

    2023-11-15
    150
  • 如何在Pycharm中删除项目

    如何在Pycharm中删除项目PyCharm是一款比较流行的Python IDE(集成开发环境),它为Python开发者提供了非常方便的开发环境。如果你是一个PyCharm用户,你可能会发现自己在使用它的时候,会有一些不必要的项目残留在你的开发环境中。那么,在这种情况下,如何从PyCharm中删除这些项目呢?本文将从多个方面详细介绍如何在Pycharm中删除项目。

    2024-09-03
    27
  • AB实验人群定向HTE模型4 – Double Machine Learning[通俗易懂]

    AB实验人群定向HTE模型4 – Double Machine Learning[通俗易懂]HTE旨在量化实验对不同人群的不同影响,进而通过人群定向进行差异化干预。Double Machine Learning把Treatment作为特征,通过估计特征对Y的影响来计算实验的差异效果。

    2023-07-22
    112
  • sql server高可用_sql server的优缺点

    sql server高可用_sql server的优缺点从SQLServer 2012以后微软推出了新的SQLServer高可用技术 ,它的名字叫AlwaysOn。
    AlwaysOn是一种集合了高可用性和灾难恢复两种功能于一体的技术,相比故障转移群集、数据

    2023-05-04
    159
  • Oracle数据泵不同用户导入导出(表级)[亲测有效]

    Oracle数据泵不同用户导入导出(表级)[亲测有效]先认识一个单词,schema:模式。 再来了解一个概念。 当创建一个用户的时候,会同时创建一个与用户同名的schema,这个schema的官方解释是对象的集合。 举个例子,比如说我就是一个用户,叫A,

    2023-05-27
    136
  • Oracle重命名sys或system操作记录[通俗易懂]

    Oracle重命名sys或system操作记录[通俗易懂]oracle等保中有条要求:应重命名或删除默认账户,修改默认账户的默认口令。给的建议是修改sys,system默认账户名称,避免使用常见用户名称;以下记录了两种方法来实现上面的要求:Oracle重命…

    2023-04-05
    162
  • 使用Python执行系统命令

    使用Python执行系统命令 Python是一种广泛使用的高级编程语言,可以用于编写脚本、web服务、自动化任务等。Python提供了执行系统命令的能力,这使得我们可以利用Python来执行与系统相关的任务,例如文件管理、进程管理、网络操作和系统监控等。使用Python执行系统命令可以提高工作效率与精度,更加方便快捷地管理系统,本文主要介绍如何使用Python执行系统命令。

    2024-06-18
    51
  • 华为云CodeArts Artifact 5大特性,揭秘大型企业制品管理面纱[通俗易懂]

    华为云CodeArts Artifact 5大特性,揭秘大型企业制品管理面纱[通俗易懂]​  华为云CodeArts Artifact用于管理源代码编译后的构建产物,支持Maven、npm、PyPI、Docker、NuGet等常见制品包类型。

    2023-08-01
    140

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注