小王的故事 小王去上班
小王是个程序员,每个工作日他都要去上班,诸多交通工具他最喜欢的交通工具是骑电车。在骑行的过程中放空自己使他很快。
突然有一天天气预报说近期有很大的雨,小王再想骑电车去上班显然是不可能了。那么他就要选择开汽车去。
但是由于小王每天过于依赖骑电动车,开汽车水平有限,那么他就要重新学习开汽车。
因此小王很烦恼,我就想去上个班,还要掌握不同的交通工具,这真是让人烦恼,难道我就想做一个单纯的打工族就这么难吗?小王就把这件事告诉了他的老婆,她老婆是个老司机,她说“这事你就不用管了,我是老司机啊,开车这事我来控制就好了,你就记得给我多买些礼物就好“。从此之后小王就安心的为了老婆的赚钱,开车这事就完全有他老婆负责。
我曾经很享受自己去上班(自己控制),每天去上班就拿出我心爱的电动车(实例化对象),直到有一天天气预报告诉我要下大雨,再依赖自行车就会被大雨淋着,而换交通工具我发现我就要重新学习开车(高耦合),知道我老婆大人说她是老司机(ioc容器),开车这事由她来控制(控制反转),不管怎么去上班,事先告诉他用什么交通工具就行(依赖注入),从此我每个工作日只要叫上我老婆她就直接带我去上班了。
依赖注入 从小王的故事我们可以看到一些关键词依赖与控制 而今天要说的就是什么是依赖注入。说到依赖注入(DI)还有个概念叫控制反转(IOC)。
控制反转(IOC—Inversion of Control)不是什么技术,而是一种设计思想。它的思路是设计好的依赖类交给容器控制,而不是在对象中直接实例化控制。就是在系统运行时ioc容器动态向一个对象提供他依赖的其他对象。而他的实现就是用依赖注入来实现。
依赖注入(DI—Dependency Injection)是组件之间依赖关系由容器决定。为此我们要明白依赖和注入关系
依赖:由于应用程序需要ioc容器提供对象外部的资源所以应用程序依赖于ioc容器。
注入:某个对象所需要的外部资源(包括对象、资源、常量数据)注入到了ioc容器中。
依赖注入是net core和net5的核心概念,我们在了解完概念之后也要对我们框架中对他的实现有个清楚的认识。当然官方文档是最好的了解方式。接下来我从我的角度去说一下对net 5(net core)依赖注入的理解.首先我们要知道net5依赖注入的实现由net 内置的容器和第三方的容器。我们主要说内置的实现情况。
内置依赖注入 Microsoft.Extensions.DependencyInjectionnet5 内置依赖注入主要用到了Microsoft.Extensions.DependencyInjection和Microsoft.Extensions.DependencyInjection.Abstraction两个引用。我们nuget引用就行。它们是开源的。
我们可以看到DependencyInjection这个项目并不大,但却是整个net5(NET Core)的基础,因为它提供了依赖注入容器的默认实现,而依赖注入是net5(net core)的核心基础. 源码解析 IServiceCollection public class ServiceCollection : IServiceCollection { //ServiceDescriptor缓存集合 private readonly List<ServiceDescriptor> _descriptors = new List<ServiceDescriptor>(); //注册到当前ServiceCollection对象中的ServiceDescriptor数量 public int Count => _descriptors.Count; public bool IsReadOnly => false; public ServiceDescriptor this[int index] { get { return _descriptors[index]; } set { _descriptors[index] = value; } } //清空所有ServiceDescriptor对象 public void Clear() { _descriptors.Clear(); } //查询ServiceCollection是否包含指定ServiceDescriptor对象 public bool Contains(ServiceDescriptor item)=> _descriptors.Contains(item); //拷贝ServiceDescriptor public void CopyTo(ServiceDescriptor[] array, int arrayIndex) =>_descriptors.CopyTo(array, arrayIndex); //从ServiceCollection移除指定ServiceDescriptor public bool Remove(ServiceDescriptor item)=>_descriptors.Remove(item); //获取此ServiceCollection的迭代器 public IEnumerator<ServiceDescriptor> GetEnumerator()=> _descriptors.GetEnumerator(); public int IndexOf(ServiceDescriptor item) => _descriptors.IndexOf(item); public void Insert(int index, ServiceDescriptor item) => _descriptors.Insert(index, item); public void RemoveAt(int index)=> _descriptors.RemoveAt(index); } IServiceCollection&&ServiceDescriptor namespace Microsoft.Extensions.DependencyInjection { /// <summary> /// 指定服务描述符集合的约定 /// </summary> public interface IServiceCollection : IList<ServiceDescriptor> { } }