2

そのため、コードを依存性注入、依存性注入コンテナー (DIC) パラダイムに切り替えたいと考えています。そして、私はそれについて読んでいます...私はすでにそれをずっとやっているように思えます...多分...

私がしていたこと - 私は通常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;
    }
}

?>

これが実際に依存性注入コンテナーであり、何が改善できるかを誰かが確認できますか?

4

3 に答える 3

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'));
于 2012-11-29T03:51:40.207 に答える
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 は、ディスクやネットワークなどの揮発性のものを扱う場合にも役立ちます。ディスクとネットワーク アクセスを「依存関係」で分離し、ネットワーク ドロップやディスクの状態変化に悩まされることなく、注入のターゲットの完全性と正確性をテストできます。

于 2012-12-06T21:43:01.573 に答える