<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ![](https://source.unsplash.com/random/1680x200) ## 依賴注入之-容器 設計架構圖 ![](https://img.kancloud.cn/ca/ab/caabe11e642b4085e9c419117ba458cc_1080x780.png) 依賴注入(Dependency Injection,DI)容器就是一個對象,它知道怎樣初始化并配置對象及其依賴的所有對象。 注冊會用到一個依賴關系名稱和一個依賴關系的定義。 依賴關系名稱可以是一個類名,一個接口名或一個別名。 依賴關系的定義可以是一個類名,一個配置數組,或者一個 PHP 回調。 ### 一、常見注入方式 #### 1、構造方法注入(Constructor Injection) 在參數類型提示的幫助下,DI 容器實現了構造方法注入。當容器被用于創建一個新對象時, 類型提示會告訴它要依賴什么類或接口。 容器會嘗試獲取它所依賴的類或接口的實例, 然后通過構造器將其注入新的對象。例如: ``` class Foo { public function __construct(Bar $bar) { } } $foo = $container->get('Foo'); // 上面的代碼等價于: $bar = new Bar; $foo = new Foo($bar); ``` #### 2、方法注入(Method Injection) 通常,類的依賴關系傳遞給構造函數,并且在整個生命周期中都可以在類內部使用。 通過方法注入,可以提供僅由類的單個方法需要的依賴關系, 并將其傳遞給構造函數可能不可行,或者可能會在大多數用例中導致太多開銷。 ```php class MyClass extends \yii\base\Component { public function __construct(/*Some lightweight dependencies here*/, $config = []) { // ... } public function doSomething($param1, \my\heavy\Dependency $something) { // do something with $something } } ``` #### 3、Setter 和屬性注入(Setter and Property Injection) Setter 和屬性注入是通過[配置](https://www.yiichina.com/doc/guide/2.0/concept-configurations)提供支持的。 當注冊一個依賴或創建一個新對象時,你可以提供一個配置, 該配置會提供給容器用于通過相應的 Setter 或屬性注入依賴。 例如: ``` use yii\base\BaseObject; class Foo extends BaseObject { public $bar; private $_qux; public function getQux() { return $this->_qux; } public function setQux(Qux $qux) { $this->_qux = $qux; } } $container->get('Foo', [], [ 'bar' => $container->get('Bar'), 'qux' => $container->get('Qux'), ]); ``` ### 二、直接注入類到容器中 TP5.1 `綁定一個類到容器中(第一個參數直接傳入類名)` **1、使用容器** ``` // 綁定類庫標識 Container::getInstance()->bindTo(GameService::class); // 自動實例化 $obj = Container::get(GameService::class); // 快速調用 halt($obj->test()); ``` **2、使用助手函數** ``` // 綁定類庫標識 bind(GameService::class); // 快速調用(自動實例化) $obj = app(GameService::class); halt($obj); ``` Yii2.0 `注冊一個同類名一樣的依賴關系` ``` $container = new \yii\di\Container; // 注冊一個同類名一樣的依賴關系,這個可以省略。 $container->set(GameService::class); ``` ### 三、綁定類標識 TP5.1 `可以對已有的類庫綁定一個標識(唯一),便于快速調用` **1、使用容器** ``` // 綁定類庫標識 Container::getInstance()->bindTo('game_service2',GameService::class); // 快速調用(自動實例化) $obj = Container::get('game_service2'); halt($obj); ``` **2、使用助手函數** ``` // 綁定類庫標識 bind('game_service',GameService::class); // 快速調用(自動實例化) $obj = app('game_service'); // 帶參數實例化調用 $obj = app('game_service',['file']); halt($obj->test()); ``` Yii2.0 `注冊一個別名` ``` $container = new \yii\di\Container; $container->set('foo', 'yii\db\Connection'); // 創建一個 Connection 實例 $obj = $container->get('foo'); ``` ### 四、綁定閉包 TP5.1 使用 ``` // 使用助手函數 bind('sayHello', function ($name) { return 'hello,' . $name; }); echo app('sayHello',['thinkphp']); // 使用容器 Container::getInstance()->bindTo('sayTinywan',function ($age){ return 'Tinywan is '.$age; }); echo Container::get('sayTinywan',[24]); ``` Yii2.0 `注冊一個 PHP 回調` ``` // 每次調用 $container->get('db') 時,回調函數都會被執行。 $container->set('db', function ($container, $params, $config) { return new \yii\db\Connection($config); }); ``` ### 四、類綁定到接口 ``` // 綁定think\LoggerInterface接口實現到think\Log bind('think\LoggerInterface','think\Log'); ``` 使用接口作為依賴注入的類型 ``` <?php namespace app\index\controller; use think\LoggerInterface; class Index { public function hello(LoggerInterface $log) { $log->record('hello,world!'); } } ``` 或者使用容器 ``` // 綁定 app\driver\DriverInterface接口實現到 app\driver\YoungDriver $driver = Container::getInstance()->bindTo(DriverInterface::class,YoungDriver::class); $car = Container::get(Car::class, [$driver]); var_dump($car->run()); ``` ## 依賴注入之-服務定位器 服務定位器是一個了解如何提供各種應用所需的服務(或組件)的對象。在服務定位器中, 每個組件都只有一個單獨的實例,并通過ID 唯一地標識。 用這個 ID 就能從服務定位器中得到這個組件。 ### TP5.1 使用 **1、配置文件`provider.php`** 系統會自動批量綁定類庫到容器中 ``` // 應用容器綁定定義 return [ 'game_player' => \app\common\repositories\player\Game::class, 'random' => \app\common\repositories\game\RandomGroup::class ]; ``` **2、那類玩家在玩那個游戲** ``` // 聲明那類玩家 Container::getInstance()->bindTo(PlayerInterface::class,TeacherPlayer::class); // 要玩那個游戲 $game = app('random'); // 獲取玩家實例 $player = app('game_player'); // 玩家開始玩什么游戲 halt($player->play($game)); ``` **3、攜帶參數** ``` // 聲明那類玩家 Container::getInstance()->bindTo(PlayerInterface::class, StudentPlayer::class); // 要玩那個游戲 $game = app('random'); // 獲取玩家實例 $parms = ['caode' => 200, 'name' => 'wangwang']; $player = app('game_player',['ddd']); // 玩家開始玩什么游戲 halt($player->play($game,$parms)); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看