<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 獲取依賴關系 向控制器,組件和服務注入依賴性有幾種可能性。 本文討論: 1、一般依賴注入,不限于Nette DI Container中的依賴關系,以及 2、控制器,組件和服務的實際示例和建議。 ## 如何獲取依賴關系? 可以通過以下方式之一將依賴注入到應用程序類中: * 通過類的構造函數, * 通過setter或成員變量, * 通過inject *方法, * 在公共成員變量上使用@inject注釋。 ******前兩種方式可以用于所有面向對象的編程語言,最后兩種可用在Nette框架中。 讓我們通過所有這些方法,然后在實際的例子中展示他們的應用。****** ### 構造函數傳遞 所有依賴關系在創建對象時傳遞。 依賴項聲明為構造函數參數,其類型在類型提示中給出: ~~~ class MyService { /** @var AnotherService */ private $anotherService; public function __construct(AnotherService $service) { $this->anotherService = $service; } } ~~~ MyService類聲明一個AnotherService類的實例必須在對象創建期間傳遞。 此聲明適用于所有強制依賴性,這是類的運行所必需的。 沒有這些依賴關系,不能實例化類。 ### 通過Setter或公共變量傳遞 這些依賴關系在對象創建后傳遞。 看看通過setter方法傳遞依賴的例子。 ~~~ class MyService { /** @var AnotherService */ private $anotherService; public function setAnotherService(AnotherService $service) { $this->anotherService = $service; } } ~~~ 這些依賴關系只能在對象創建后傳遞。 此方法僅適用于非強制依賴項,因為不能保證依賴項將傳遞到對象。 傳遞一個公共變量的工作方式非常相似: ~~~ class MyService { /** @var AnotherService */ public $anotherService; } ~~~ 但是,不建議使用此方法,因為變量必須聲明為public,并且沒有辦法如何確保傳遞的對象將是給定類型。 我們也失去了在我們的代碼中處理所分配的依賴性的能力,并且我們違反了封裝的原理。 ### 通過注入*方法 此方法特定于Nette框架中的DI容器。 它是setter方法的一種特殊情況,它以inject *前綴開始。 ~~~ class MyService { /** @var AnotherService */ private $anotherService; public function injectAnotherService(AnotherService $service) { $this->anotherService = $service; } } ~~~ 該類可以包含多個inject *方法,每個方法都有多個參數和一個唯一的名稱。 Nette能夠在控制器中找到這些方法,并自動使用適當的參數調用它們。 也可以在配置文件中的服務中啟用此行為。 這將在后面說明。 ### @inject注釋 第二種方法特定于Nette 框架。 它是一個通過公共變量傳遞的特殊情況。 變量在docblock注釋中由@inject注釋標記: ~~~ class MyService { /** @inject @var \App\AnotherService */ public $anotherService; } ~~~ Nette框架還可以掃描這些變量的呈現器并自動注入這些依賴項。 @var注釋中的變量類型必須由其完全限定名稱(包括命名空間)給出。 使用指令中定義的別名可以從版本2.2開始使用。 這種方法具有與普通傳遞公共變量相同的缺點 - 我們不能強制傳遞依賴的類型。 然而,代碼非常簡單和短,這在某些情況下可能是一個優勢。 ### 我應該選擇哪種方式? 通過setter傳遞和傳遞可選依賴項的構造方法可用于所有實例化的類。 以下兩種技術,通過inject *方法傳遞依賴性以及由@inject注釋標記的公共變量,是較不干凈的技術,并且僅在具有顯式配置的DI容器中的控制器和服務中可用。 我們僅在少數特定情況下使用它們。 所有這些方法有一個共同點是,自動接線僅適用于由Nette DI Container或Nette中的一個工廠創建的對象。 當我們通過調用new創建對象時,我們必須手動傳遞依賴。 讓我們來看看依賴注入的例子和優選方法。 ### 控制器 Nette框架中的控制器是由PresenterFactory創建。 這個工廠還自動注入依賴關系聲明: 1、在構造函數中, 2、使用inject *方法, 3、通過公共屬性與@inject注釋。 下面的控制器展示了依賴傳遞的所有三種方式: ~~~ class MyPresenter extends Nette\Application\UI\Presenter { // 1) 構造函數傳遞: private $service1; public function __construct(Service1 $service) { $this->service1 = $service; } // 2) 使用inject *方法: private $service2; public function injectService2(Service2 $service) { $this->service2 = $service; } // 3)帶@inject注釋的公共變量: /** @inject @var \App\Service3 */ public $service3; } ~~~ 傳遞控制器的依賴項的首選方法是使用構造函數,或者在父控制器使用inject *方法的情況下。 在父呈現者中使用inject *方法允許我們保留封裝,并保持構造子對子呈現者是干凈的。 我們也可以使用@inject注釋的兩種情況,但我們必須記住,這打破了封裝。 不建議通過構造函數將依賴傳遞給父提交者,因為它在使用提交者繼承時使構造函數簽名變得復雜:您必須獲取并傳遞依賴關系到所有父提交者類。 ## 組件 組件通常直接在控制器的代碼中實例化,或通過應用程序特定的工廠實例化。 在這些情況下,Nette不能自動注入依賴項,并且不能使用inject *方法或變量與@inject注釋。 讓我們考慮我們有以下組件: ~~~ class MyControl extends Nette\Application\UI\Control { // 1) 構造函數傳遞: private $service1; public function __construct(Service1 $service) { parent::__construct(); $this->service1 = $service; } // 2) setter注入的可選依賴關系: private $service2; public function setService2(Service2 $service) { $this->service2 = $service; } } ~~~ 該組件可以以下列方式用于控制器: ~~~ class MyPresenter extends Nette\Application\UI\Presenter { /** @inject @var \App\Service1 */ public $service1; /** @inject @var \App\Service2 */ public $service2; protected function createComponentMyControl() { $control = new MyControl($this->service1); $control->setService2($this->service2); return $control; } } ~~~ 因為依賴關系不是由DI容器自動注入的,所以我們必須在類中獲取所有需要的依賴關系,這將創建我們的組件 - 在我們的示例中的控制器。 如果我們在另一個組件中創建組件,組件依賴項將被添加到父組件的依賴項: ~~~ class MySecondControl extends Nette\Application\UI\Control { // MySecondControl的依賴關系: private $service3; // 子類的依賴MyControl: private $service1; private $service2; public function __construct(Service1 $service1, Service2 $service2, Service3 $service3) { parent::__construct(); //向成員分配依賴關系$service1, $service2, $service3 } protected function createComponentMyControl() { $control = new MyControl($this->service1); $control->setService2($this->service2); return $control; } } ~~~ 因為我們通常手動實例化組件,依賴注入的首選方式取決于依賴是強制還是可選。 構造函數應該用于強制依賴和setter為可選。如果我們使用構造函數進行依賴傳遞,我們不能忘記從父類中調用構造函數:parent :: __ construct()! ## 服務 服務被注冊在DI容器中,因此依賴性被自動傳遞。 我們只能在構造函數中聲明依賴關系,除非我們提供額外的配置: ~~~ services: service1: App\Service1 ~~~ 在此服務的構造函數中聲明的所有依賴項都將自動傳遞: ~~~ namespace App; class Service1 { private $anotherService; public function __construct(AnotherService $service) { $this->anotherService = $service; } } ~~~ 構造函數傳遞是服務的依賴注入的首選方式。 如果我們想通過setter傳遞依賴,我們可以添加setup部分到服務定義: ~~~ services: service2: class: App\Service2 setup: - setAnotherService ~~~ 服務類別: ~~~ namespace App; class Service2 { private $anotherService; public function setAnotherService(AnotherService $service) { $this->anotherService = $service; } } ~~~ 我們還可以添加inject:yes指令。 這個指令將啟用自動調用inject *方法和使用@inject注釋將依賴項傳遞給公共變量: ~~~ services: service3: class: App\Service3 inject: yes ~~~ 依賴Service1將通過調用inject *方法傳遞,依賴Service2將被分配給$ service2變量: ~~~ namespace App; class Service3 { // 1) inject* method: private $service1; public function injectService1(Service1 $service) { $this->service1 = $service1; } // 2) Assign to the variable with the @inject annotation: /** @inject @var \App\Service2 */ public $service2; } ~~~ 其他可能性 還有一些其他的可能性,我們如何可以改變控制器和組件的配置和依賴注入。 ### 控制器即服務 從Nette 2.1開始,您可以將控制器注冊為配置文件的服務。 它將作為DI容器中的任何其他服務創建。 您可以傳遞任何不能自動連接的參數(字符串,數字等),并添加setter調用。 所有inject *方法將被自動調用,并且所有的依賴關系將被自動分配給帶有@inject注釋的公共變量。 你不必添加inject:yes指令。 配置文件中的控制器定義可以如下所示: ~~~ services: - App\Presenters\ImagePresenter("%wwwDir%/media") ~~~ ~~~ class ImagePresenter extends Nette\Application\UI\Presenter { private $imageDir; private $optimizer; public function __construct($imageDir, ImageOptimizer $optimizer) { $this->imageDir = $imageDir; $this->optimizer = $optimizer; } } ~~~ 來自配置的字符串將作為構造函數的第一個參數傳遞,其余參數將自動連接。 但是,在設計控制器時必須小心。 所有應用程序邏輯應在服務中,而不是在控制器中。 對附加呈現者配置的需要通常是挑戰的不良分解的標志。 ## 組件工廠 像控制器一樣,組件也可以在配置文件中注冊。 然而,控制器通常在處理單個請求期間僅創建一次,而組件可以在多個位置被實例化。 因此,我們必須注冊一個組件工廠,而不是一個服務。 從Nette 2.1開始,我們可以使用從接口生成的工廠。 接口必須在方法的@return注釋中聲明返回類型。 Nette將生成適當的實現接口。 接口必須只有一個名為create的方法。 我們的組件工廠接口可以通過以下方式聲明: ~~~ namespace App\Components; interface IUserTableFactory { /** * @return UserTable */ public function create(); } ~~~ create方法將使用以下定義實例化UserTable組件: ~~~ amespace App\Components; class UserTable extends Control { private $userManager; public function __construct(UserManager $userManager) { $this->userManager = $userManager; } } ~~~ 工廠將在config.neon文件中注冊: ~~~ services: - App\Components\IUserTableFactory ~~~ Nette將檢查所聲明的服務是否是一個接口。 如果是,它還會生成相應的實現工廠。 定義也可以寫成更詳細的形式: ~~~ services: userTableFactory: implement: App\Components\IUserTableFactory ~~~ 這個完整的定義允許我們使用參數和設置部分聲明組件的附加配置,類似于所有其他服務。 在控制器中,我們只需要獲取工廠實例并調用create方法: ~~~ class UserPresenter extends Nette\Application\UI\Presenter { /** @var \App\Components\IUserTableFactory @inject */ public $userTableFactory; protected function createComponentUserTable() { return $this->userTableFactory->create(); } } ~~~ 構造器依賴項將自動傳遞到創建的控件。
                  <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>

                              哎呀哎呀视频在线观看