2012-11-29 123 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也很有用。您可以在“依赖性”中分离磁盘和网络访问,并测试注入目标的完整性和正确性,而不会受到网络丢失或磁盘状态更改的影响。