依赖注入时编程手段中解耦和封装的一个很是重要的手段,我本人已经到了没有DI没法编写项目的程度了,在.NET Framework中微软并无在FCL中引入DI,虽然推出了“Unity”。而在.NET Core中DI几乎是全部组件的标配可见DI有多么的重要,本节主要简单介绍下微软在.NET Core中加入的DI组件。java
提及DI不得不提IoC这个模式,不少人会把DI和IoC混为一谈,但其实这二者是概念和实现的关系。编程
依赖倒置原则(DIP):软件设计原则,要依赖于抽象,不要依赖具体实现。函数
控制反转(IoC):一种实现DIP原则的模式。工具
依赖注入(DI):IoC的具体实现。ui
DIP就比如一个目标一个法则。搜索引擎
IoC就比如是论文,“应该怎么作才能遵循DIP”spa
DI就比如是实际的产品,“落实到具体的语言的工具”设计
关于这个比喻可能不是很准确,你们能够使用搜索引擎去了解更为详细的差别。3d
在我接触的不少.NET项目中,不多有人使用DI,更别提像Orchard那样把DI用得出神入化。而复杂的代码很大一部分的缘由是没有引入DI。在java中几乎从刚入门的新手都使用Spring提供的DI。blog
生命周期是指对服务实例的存活状态控制,"Microsoft.Extensions.DependencyInjection"提供了一个枚举定义了三种生命周期状态。
类型 | 描述 |
Singleton | 单例服务,从当前服务容器中获取这个类型的实例永远是同一个实例。 |
Scoped | 域内单例,为每一个做用域建立一个服务实例,也就是说域内单例(域相似子容器)。 |
Transient | 瞬态,从服务容器中每获取一次建立一个新的实例。 |
代码以下:
其实能够很容易的看出,服务注册是经过建立一个“ServiceDescriptor”来完成的,而其它方式的注册只不过是基于一个方法的封装而已,让使用者能够更为方便的进行服务注册。
咱们能够经过不少手段去注册一个服务,但这里推荐你们优先使用扩展方法进行服务注册,由于这样的代码更易读。反射循环注入时能够使用其它方式。
首先咱们来看一下服务提供者提供的方法签名。
能够发现与服务注册同样,基于同一个方法提供了不少扩展方法让使用者更加便捷的获取服务。
咱们先来看“GetService<T>”与“GetRequiredService<T>”这两个方法。
这两个方法很是接近,惟一不一样的是GetRequiredService会在找不到服务的时候抛出异常,而GetService在找不到服务时会返回null。
“GetServices”这个方法是用来获取多个服务实例,该方法会返回该类型注册的多个服务实例。咱们来看个例子:
咱们能够经过运行结果很好的理清各个生命周期的用意。下面用一张图来讲明较复杂状况下“scope”的服务结果。
开发过程当中常常有一种状况,服务A的A方法依赖了服务B,而服务A的B方法依赖了服务C,这时候你就得在构造函数上同时声明服务B和C,就像这样。
这在其它DI组件中很是常见,好比autofac。而在如今咱们须要这样作:
.NET技术栈QQ群:384413261(点击加入.NET Group)