zoukankan      html  css  js  c++  java
  • 依赖注入,没那么复杂

    依赖注入


    没那么复杂

    很多时候我们会将问题复杂化,而问题的答案却一如既往的简单。

    public class Stupid
    {
        protected IService Service { get; private set; }
        public Stupid()
        {
            Service = new ConcreteServiceA();
        }
    }
    
    public class Smart
    {
        protected IService Service { get; private set; }
        public Smart(IService service)
        {
            Service = service;
        }
    }
    

    上面是两段看上去极其相似的类型代码,区别在于 Service 属性的初始化。前者在创建类型实例的时候直接创建Service的实例,而后者则不同:

    // 假设已经有一个 IService 的实例引用:concreteServiceA
    var smart = new Smart(concreteServiceA);
    

    这就是 依赖注入(Dependency Injection,DI)

    当然,这只是依赖注入的其中一种形式,因为我们至少听说过以下三种形式的依赖注入: 构造函数注入属性注入方法注入。没错,按照前面的思路,属性注入就是给属性赋值,方法注入就是用指定的参数调用方法 —— 他们都是传递一些东西(一般是另一个对象的引用)给某个对象。

    是什么在误导我们

    站在过高的角度上去看问题,难免会看不透问题的本质。

    我们接触 依赖注入,往往起源于某个 依赖注入框架(NInject,Autofac,Castle,Unity......)。从那时起我们开始在 依赖注入框架 划定的高度上入手 依赖注入。容器?注册?解析?......依赖注入框架为我们提供了丰富强大的功能,同时也带来了一大堆概念。然之后,我们还是没搞清楚依赖注入是什么,有什么优势,甚至开始怀疑它的可用性。

    可是,整个圈子都在夸赞和使用的东西,怎么可能没有利用价值呢? —— 把 依赖注入框架 当成 依赖注入,误导我们的,不是别人,是我们自己。

    控制反转

    说到依赖注入,就不得不提 控制反转(Inversion of Control,IoC):它不是具体技术,而是一种设计思想

    前文提到的 Stupid 类型,看上去也无伤大雅,很是美观易读。可是,IService 接口的设计初衷是什么呢? Service 属性值的创建已经由 Stupid 类型的构造器完成了,IService 接口为我们带来的 多态性 在这个类里面俨然不复存在;属性值将随着 Stupid 类型实例的消逝而被回收,也不可能再被重复利用。在设计上,我们将这种情况称为 紧耦合 —— IService 接口成了摆设,ConcreteServiceAStupid 二者已是密不可分的存在。

    显然,这是不合理的,我们需要改变 —— 将 Service 属性值的创建和生命周期管理交由 Stupid 类以外的地方去控制,就像 Smart 类型那样。

    对的,这就是 控制反转。跟依赖注入一样,没那么复杂。

    控制反转(IoC) VS 依赖注入(DI)

    事实上这两者并没有什么可比性。记住一句话即可:控制反转 是一种设计思想,而 依赖注入 是 控制反转 的实现方式之一。没错,之一,因为 IoC 的实现方式不只是 DI。

  • 相关阅读:
    租房
    NetBeans 时事通讯(刊号 # 103 May 18, 2010)
    美国的车库文化
    新《三国》的两点观后感
    欧洲足球逐渐失去冷门的魅力
    NetBeans 时事通讯(刊号 # 102 May 14, 2010)
    NetBeans 时事通讯(刊号 # 103 May 18, 2010)
    HTML 简史
    租房
    HTML 简史
  • 原文地址:https://www.cnblogs.com/ideck/p/about_di.html
Copyright © 2011-2022 走看看