ThinkPHP6.0 容器和依赖注入


分为如下两部分:

  1. 依赖注入
  2. 容器

  1. 依赖注入

    1. 依赖注入其实本质上是指对类的依赖通过构造器完成自动注入;

    2. 在控制器架构方法和操作和方法中一旦对参数进行对象类型约束则会自动触发依赖注入,由于访问控制器的参数都来自于 URL 请求,普通变量就是通过参数绑定自动获取,对象变量则是通过依赖注入生成。

    3. 案例:

      // 模型层 One
      namespace app\model;
      use think\Model;
      class One extends Model
      {
          public $username = 'laowen';
      }
      
      // 控制器
      namespace app\controller;
      use app\model\One;
      class TestOne
      {
       protected $one;
          public function __construct(One $one)
          {
             $this->one = $one;
          }
          public function index()
          {
             return $this->one->username;
          }
      }
      
    4. 依赖注入:即允许通过类的方法传递对象的能力,并且限制了对象的类型(约束);

    5. 而传递的对象背后的那个类被自动绑定并且实例化了,这就是依赖注入;

    6. 支持使用依赖注入的场景包括(但不限于):

      • 控制器架构方法;
    • 控制器操作方法;

      • 路由的闭包定义;
      • 事件类的执行方法;
      • 中间件的执行方法;
  2. 容器

    1. 依赖注入的类统一由容器管理的,大多数情况下是自动绑定和自动实例化的;

    2. 如果想手动来完成绑定和实例化,可以使用bind()和app()助手函数来实现;

      class TestTwo
      {
        public function bind()
        {
          	bind('one', 'app\model\One');
          	return app('one')->username;
         }
      }
      // bind('one' ,'...')绑定类库标识,这个标识具有唯一性,以便快速调用;
      // app('one') 快速调用,并自动实例化对象,标识严格保持一致包括大小写;
      
    3. 自动实例化对象的方式,是采用单例模式实现,如果想重新实例化一个对象,则:

      class TestTwo
      {
        public function bind()
        {
          	bind('one', 'app\model\One');
          	// 每次调用总是会重新实例化
          	return app('one',[], true)->username;
      
          	// app()中第二参数,方法实例化对象的时候,传递参数;
          	// 模型层通过构造函数来接收数据
          	// $one = app('one', [['test']], true);
      			// return $one->username;
         }
      }
      
    4. 通过 app() 绑定一个类到容器中并自动实例化;

      class TestTwo
      {
        public function bind()
        {
          	return app('app\model\One')->username;
        }
      }
      
    5. 批量绑定到容器中

      public function bind()
      {
        bind([
          'one' => 'app\model\One',
          'user' => 'app\model\User'
        ]);
      
        // bind([
      	// 	'one' => \app\model\One::class,
        //  'user' => \app\model\User::class
      	// ]);
        // ::class 模式,不需要单引号;
        // 而是需要在最前面加上\,之前的加不加都行;
        return app('one')->username;
      }
      
    6. 系统提供了 provider.php 文件,用于批量绑定类到容器中;

    7. 系统内置了很多常用的类库,以便开发者快速调用;