4. 依赖注入


    injector , 我从 ng 的文档中得知这个概念,之后去翻看源码时了解了一下这个机制的工作原理。感觉就是虽然与自己的所想仅差那么一点点,但就是这么一点点,让我感慨想象力之神奇。



    先看我们之前代码中的一处函数定义:

    1. var BoxCtrl = function($scope, $element){}


    在这个函数定义中,注意那两个参数: $scope$element ,这是两个很有意思的东西。总的来说,它们是参数,这没什么可说的。但又不仅仅是参数——你换个名字代码就不能正常运行了。



    事实上,这两个参数,除了完成“参数”的本身任务之外,还作为一种语法糖完成了“依赖声明”的任务。本来这个函数定义,完整的写法应该像 AMD 声明一样,写成:

    1. var BoxCtrl = ['$scope', '$element', function(s, e){}];


    这样就很明显,表示有一个函数,它依赖于两个东西,然后这两个东西会依次作为参数传入。



    简单起见,就写成了一个函数定义原本的样子,然后在定义参数的名字上作文章,来起到依赖声明的作用。



    在处理时,通过函数对象的 toString() 方法可以知道这个函数定义代码的字符串表现形式,然后就知道它的参数是 $scope$element 。通过名字判断出这是两个外部依赖,然后就去获取资源,最后把资源作为参数,调用定义的函数。



    所以,参数的名字是不能随便写的,这里也充分利用了 js 的特点来尽量做到“反省”了。



    在 Python 中受限于函数名的命名规则,写出来不太好看。不过也得利于反省机制,做到这点也很容易:

    1. # -- coding: utf-8 --

      def f(Ia, Ib):
      print Ia, Ib

      args = f.func_code.co_varnames
      SRV_MAP = {
      'Ia': '123',
      'Ib': '456',
      }

      srv = {}
      for a in args:
      if a in SRV_MAP:
      srv[a] = SRV_MAP[a]
      f(**srv)