依赖注入(DI,Dependency Inject)与控制反转(IoC,Invertion of Contorl)在许多框架中都存在,如spring、.net、nest等。很多小伙伴都听说过,却不是很了解。

解释

控制反转(IoC),是一种设计原则(设计思想)。用于对象与对象之间的解耦。在传统编程中,对象通常会自行创建和管理其依赖对象,导致组件之间的耦合度高。实现依赖注入的方式就是通过控制反转,将创建对象和依赖关系过程交给外部容器。

class A
{
    constructor(B){
      // 因为A掌控B的创建,因此A控制了B
      this.b = new B();
    }
} 

依赖注入(Dependency Inject,DI),也叫注入,是一种设计模式(具体实现)。将对象的创建和依赖关系管理由外部容器负责,而不是在具体使用到对象的地方管理。

class A
{
    // B由外部注入,称之为依赖注入
    constructor(B)
    {
        // B由外部创建,脱离了A的控制,称之为控制反转
        this.b = B;
    }
} 

为什么需要依赖注入和控制反转

解耦

相信大家都听说过一个法则:“高内聚,低耦合”,第一张图,B 依赖了 A,而 C 通过依赖 B 依赖了 A,稍微多一点这种关系,就会很复杂,难以维护。如果 我们把 B 和 C 所依赖的功能向 A 内聚,那么 B 和 C 就实现了解耦。

还有一种方式是做抽象的接口,只要遵循一定的规则,你就可以把具体的实现使用到这个接口上,这也是解耦。比如内存卡,使用内存卡的设备只是一个接口,而内存卡就是这个接口的具体实现,所以你就可以把不同的内存卡(遵循标准生产的)使用到这个设备上。

IoC 容器

在项目里,通常会遇到两个关于对象的问题,一个是对象数量多,如何统一管理对象的创建和销毁,依赖一个问题是对象间的依赖错综复杂,如何管理他们的依赖关系?

针对上述问题,解决方案就是 IoC 容器,IoC 容器是一个对象管理器,它统一管理对象的创建过程、生命周期、依赖关系,以及提供自动注入,根据配置创建对象的功能。

开源IoC容器Autofac:

using Autofac;

namespace AutofacDemo
{
    class A
    { }

    class B
    {
        A _a;
        // 只需要声明需要注入的对象,由容器自动完成依赖对象的创建与注入
        public B(A a)
        {
            _a = a;
        }
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            // 将类型注册至容器中
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<A>();
            // 设置对象的生命周期(单例模式)
            builder.RegisterType<B>().SingleInstance();

            // 构造IoC容器
            IContainer container = builder.Build();
            // 从容器中获取对象
            B b = container.Resolve<B>();
        }
    }
}