2012-11-29 121 views
2

所以 - 我想將我的代碼切換到依賴注入,依賴注入容器(DIC)範例。我一直在閱讀...它似乎對我來說,我一直在做這一切......也許......PHP依賴注入。我的代碼實際上是依賴注入容器嗎?

我在做什麼 - 我正在創建名稱空間類(容器? ),我通常會調用Api,爲每個單獨的項目,然後實例化並從中獲取已配置的對象。實際示例:

<?php 

/** 
* @namespace 
*/ 
namespace SomeNamespace; 

/** 
* api 
*/ 
class api { 
    public function __construct() { 
     /* 
     * Requiring all of the common files. 
     */ 
     require_once(VENDORS_PATH . DIRECTORY_SEPARATOR . 'PHPMailer' . DIRECTORY_SEPARATOR . 'class.phpmailer.php'); 
     require_once(VENDORS_PATH . DIRECTORY_SEPARATOR . 'PHPMailer' . DIRECTORY_SEPARATOR . 'class.smtp.php'); 
    } 

    private function getPostgresqlPreprocessor() { 
     $spp = new \SomeNamespace\Utils\PostgresSearchPreProcessor(); 
     $settingsService = $this->getSettingsService(); 
     $settings = $settingsService->readSettings(); 
     $spp->setValidator(new \Auro\Validation\Validator()) 
      ->setSettings($settings) 
      ->setConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php')); 
     return $spp; 
    } 

    public function getDalApi() { 
     return new \DalServices\Api(); 
    } 

    public function getFeedsService() { 
     $fc = \Auro\Mvc\Front::getInstance(); 
     $feedsService = new \SomeNamespace\Feeds(); 
     $renderer = new \Auro\View\Renderer(); 
     $renderer->setBasePath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'feeds'); 

     $feedsService 
      ->setDalApi(new \DalServices\Api()) 
      ->setSomeNamespaceApi($this) 
      ->setResponse($fc->getResponse()) 
      ->setPaginator(new \Auro\View\Paginator())    
      ->setConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_feeds_config.php')) 
      ->setCams(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'webcams.php')) 
      ->setRenderer($renderer); 
     return $feedsService; 
    } 

    public function getSettingsService() { 
     $fc = \Auro\Mvc\Front::getInstance(); 
     $settingsService = new \SomeNamespace\Settings; 
     $renderer = new \Auro\View\Renderer(); 
     $renderer->setBasePath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'settings'); 

     $settingsService 
      ->setSomeNamespaceApi($this) 
      ->setValidator(new \Auro\Validation\Validator()) 
      ->setConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php')) 
      ->setDalApi(new \DalServices\Api()) 
      ->setResponse($fc->getResponse()) 
      ->setRenderer($renderer); 
     return $settingsService; 
    } 

    public function getUsersService() { 
     $fc = \Auro\Mvc\Front::getInstance(); 
     $usersService = new \SomeNamespace\Users(); 
     $renderer = new \Auro\View\Renderer(); 
     $renderer->setBasePath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'users'); 
     $usersService 
      ->setSomeNamespaceApi($this) 
      ->setValidator(new \Auro\Validation\Validator()) 
      ->setConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php')) 
      ->setAvailableCurrencies(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'currencies.php')) 
      ->setLanguages(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'languages.php'))   
      ->setPostgersqlPreprocessor($this->getPostgresqlPreprocessor()) 
      ->setResponse($fc->getResponse()) 
      ->setDalApi(new \DalServices\Api()) 
      ->setRenderer($renderer); 
     return $usersService; 
    } 

    public function getVrcommentsService() { 
     $fc = \Auro\Mvc\Front::getInstance(); 
     $vrcommentsService = new \SomeNamespace\Vrcomments(); 
     $renderer = new \Auro\View\Renderer(); 
     $renderer->setBasePath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'vrcomments'); 
     $vrcommentsService 
      ->setSomeNamespaceApi($this) 
      ->setValidator(new \Auro\Validation\Validator()) 
      ->setConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php')) 
      ->setPostgersqlPreprocessor($this->getPostgresqlPreprocessor()) 
      ->setPaginator(new \Auro\View\Paginator()) 
      ->setResponse($fc->getResponse()) 
      ->setDalApi(new \DalServices\Api()) 
      ->setRenderer($renderer); 
     return $vrcommentsService; 
    } 

    public function getVrentalsService() { 
     $fc = \Auro\Mvc\Front::getInstance(); 
     $renderer = new \Auro\View\Renderer(); 
     $renderer->setBasePath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'vrentals'); 
     $vrentalsService = new \SomeNamespace\Vrentals(); 
     $vrentalsService 
      ->setSomeNamespaceApi($this) 
      ->setValidator(new \Auro\Validation\Validator()) 
      ->setConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php')) 
      ->setPostgersqlPreprocessor($this->getPostgresqlPreprocessor()) 
      ->setPaginator(new \Auro\View\Paginator()) 
      ->setDalApi(new \DalServices\Api()) 
      ->setRenderer($renderer) 
      ->setResponse($fc->getResponse()) 
      ->setMailConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_mail.php')) 
      ->setMailer(new \PHPMailer(true)); 
     return $vrentalsService; 
    } 

    public function getNoAikService() { 
     $fc = \Auro\Mvc\Front::getInstance(); 
     $renderer = new \Auro\View\Renderer(); 
     $renderer->setBasePath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'noaik'); 
     $AikService = new \SomeNamespace\Noaik(); 
     $noAikService 
      ->setSomeNamespaceApi($this) 
      ->setValidator(new \Auro\Validation\Validator()) 
      ->setConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php')) 
      ->setPostgersqlPreprocessor($this->getPostgresqlPreprocessor()) 
      ->setPaginator(new \Auro\View\Paginator()) 
      ->setResponse($fc->getResponse()) 
      ->setDalApi(new \DalServices\Api()) 
      ->setRenderer($renderer) 
      ->setMailConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_mail.php')) 
      ->setMailer(new \PHPMailer(true)); 
     return $noAikService; 
    } 

    public function getTotalauthService() { 
     $fc = \Auro\Mvc\Front::getInstance(); 
     $renderer = new \Auro\View\Renderer(); 
     $renderer->setBasePath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'totalauth'); 
     $totalauthService = new \SomeNamespace\Totalauth(); 
     $totalauthService 
      ->setSomeNamespaceApi($this) 
      ->setValidator(new \Auro\Validation\Validator()) 
      ->setRenderer($renderer) 
      ->setResponse($fc->getResponse()) 
      ->setDalApi(new \DalServices\Api()) 
      ->setConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_totalauth_config.php')) 
      ->setMailConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_totalauth_mail.php')) 
      ->setMailer(new \PHPMailer(true)); 
     return $totalauthService; 
    } 

    public function getQuickmailService() { 
     $fc = \Auro\Mvc\Front::getInstance(); 
     $quickmailService = new \SomeNamespace\Quickmail(); 
     $quickmailService 
      ->setSomeNamespaceApi($this) 
      ->setValidator(new \Auro\Validation\Validator()) 
      ->setResponse($fc->getResponse()) 
      ->setMailConfig(require(CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_quickmail_mail.php')) 
      ->setMailer(new \PHPMailer(true)); 
     return $quickmailService; 
    } 
} 

?> 

有人可以確認這實際上是依賴注入容器,什麼可以改進?

+0

它看起來不像一個普通的DI容器。這只是一種服務定位器。請參閱https://github.com/ninject/ninject/wiki/Dependency-Injection-By-Hand並在最後按照鏈接(這是C#,但我相信你會明白的)。在閱讀第二頁後,你會發現DI容器通常是接口和特定實現之間的粘合層。所以你請求「給我一些IFoo接口的實現」並檢索一個特定的對象。 – zerkms

+0

您也可以閱讀http://mnapoli.github.com/PHP-DI/它是PHP的依賴注入容器 –

回答

1

對我來說,這看起來像一個實例化特定API所需對象的方法的集合。我不知道我會認爲它本身就是依賴注入。儘管沒有看到這個班如何實際使用,但很難說。對我來說,一個依賴注入容器基本上會包含有關如何實例化實現一個通用接口的各種類的元數據。

這樣的可能相互作用來實現依賴注入類的樣本集可能看起來像:

class db_dependency_provider { 
    private static $class_map = array(
     'postgres' => 'postgres_abstraction_class', 
     'mysql' => 'mysql_abstraction_class', 
     'oracle' => 'oracle_abstraction_class' 
    } 

    public static function get_db_abstraction($type) { 
     $class = self::$class_map[$type]; 
     return new $class(); 
    } 
} 

interface db_abstraction_interface { 
    public function connect(); 
    public function query($query); 
    // etc. 
} 

class mysql_db_abstraction implements db_abstraction_interface { 
    // actual implementation 
} 

class postgres_db_abstraction implements db_abstraction_interface { 
    // actual implementation 
} 

class some_class_that_needs_a_db { 
    $db = null; 
    public function __construct($db) { 
     $this->db = $db; 
    } 
    // other methods 
} 

// use dependency injection container 
$class = new some_class_that_needs_a_db(db_dependency_provider::get_db_abstraction('mysql')); 
0

這不是真正的依賴注入。

依賴注入是當一段代碼依賴於另一段代碼時。方法簽名和期望的返回值是已知的,但實現不是。你完全可以在PHP中做到這一點,但它與你所做的不同。

這是依賴注入的可能是什麼樣子(完全人爲的例子):

<?php 
class PartnerAttachmentReader implements AttachmentReader{ 
    private $titleParsingStrategy; 

    private function __construct($titleParsingStrategy){ 
    $this->titleParsingStrategy = $titleParsingStrategy; 
    } 

    public static function getInstance($titleParsingStrategy){ 
    return new PartnerAttachmentReader($titleParsingStrategy); 
    } 

    public function getTitle($attachment){ 
    $this->titleParsingStrategy->parseTitle($attachment) 
    } 

    public function parseAttachment(){ 
    //Do Some Parsing 
    } 

} 
?> 

什麼是$titleParsingStrategy?它是如何工作的?未知。關鍵是我不必在意。我可以在休閒場合替換其他實現,包括模擬測試。

當處理磁盤或網絡等易失事物時,DI也很有用。您可以在「依賴性」中分離磁盤和網絡訪問,並測試注入目標的完整性和正確性,而不會受到網絡丟失或磁盤狀態更改的影響。