/蚂蚁/p/7130293.html
前言
DIP、IOC、DI
说到DI就不得不提IoC模型,很多人都会混淆DI和IoC,但其实二者是概念和实现的关系。
依赖倒置原则(DIP):软件设计原则,依赖于抽象,而不是具体的实现。
控制反转(IoC):实现DIP原则的模式。
依赖注入(DI):IoC 的具体实现。
DIP 就像一个目标和一条规则。
IoC就像一篇论文,“我应该怎么做才能遵循DIP”
DI 就像一个实际的产品,“用特定语言实现的工具”
这个比喻可能不太准确。你可以使用搜索引擎来更详细地了解其中的区别。
在 .NET 中
在我做过的很多.NET项目中,很少有人用DI,更别说像Orchard这样用得好了,代码复杂很大一部分原因就是没有引入DI,而Java中,几乎所有的初学者都是使用Spring提供的DI。
依赖注入生命周期
生命周期是指对服务实例的生存状态的控制。“Microsoft.Extensions.DependencyInjection”提供了一个枚举,定义了三种生命周期状态。
用例服务
代码如下:
注册服务的N种方法
其实,不难看出,服务的注册是通过创建“ServiceDescriptor”来完成的,而其他的注册方式只不过是基于方法的封装,让用户能够更加便捷的注册服务。
我们可以用很多种方式来注册一个服务,但是这里我们推荐大家优先使用扩展方法来注册服务,因为这样的代码比较容易阅读。其他方法可以采用反射循环注入的方式。
使用服务
首先我们来看一下服务提供者提供的方法签名。
可以发现与服务注册类似,在同一个方法基础上提供了很多的扩展方法,以便于用户更加便捷的获取服务。
我们先来看一下“GetService”和“GetRequiredService”这两个方法。
这两个方法很相似,唯一的区别在于GetRequiredService在找不到服务时会抛出异常,而GetService在找不到服务时会返回null。
“GetServices”方法用于获取多个服务实例。该方法将返回为该类型注册的多个服务实例。我们来看一个例子:
服务生命周期
我们可以通过运行结果来清晰的了解每个生命周期的用途,下图展示了一个比较复杂情况下“scope”的服务结果。
尖端
注册支持延迟加载的服务
在开发过程中经常会出现这样的情况,服务A的方法A依赖于服务B,而服务A的方法B依赖于服务C,这种情况下,你就要在构造函数中声明服务B和服务C,就像这样。
这在其他 DI 组件中很常见,例如 autofac。现在我们需要这样做: