2011-07-12 3 views
3

Je suis en train de construire une application MVC en PHP (n'utilisant aucun framework). J'utilise yadif (https://github.com/beberlei/yadif) pour l'injection de dépendance.Adaptateurs et injection de dépendances

Je voudrais construire un module de connexion. Il devrait être capable d'utiliser des adaptateurs, par exemple on pourrait être en mesure de définir que les connexions sont authentifiées en utilisant la base de données MySQL ou un répertoire LDAP. Ce paramètre serait effectué dans la zone d'administration et stocké dans une base de données.

Je suppose que je devrais un adaptateur abstrait:

<?php 
abstract AbstractLoginAdapter{ 
    abstract function login($username, $pass){} 
} 

Je voudrais donc simplement mettre en œuvre des adaptateurs comme ceci:

<?php 
MySQLLoginAdapter extends AbstractLoginAdapter{ 

    public function login($username, $pass){ 
     //do stuff 
    } 
} 

C'est tout beau et bien, mais comment puis-je créer une instance de l'adaptateur? En règle générale, les dépendances seraient injectées à l'aide yadif par le constructeur:

<?php 
class loginController{ 

    private $_adapter; 

    public function __construct(AbstractLoginAdapter $adapter){ 
      $this->_adapter = $adapter; 
    } 
} 

Cependant, puisque je ne sais pas quel adaptateur béton sera injecté, je ne peux pas définir que dans une configuration avant la main. Yadif me permet de créer une configuration que je dois ensuite passer au conteneur:

$builder = new Yadif_Builder(); 
$builder->bind("loginController") 
    ->to("loginController") 
    ->args($SelectedLoginAdapter); 

Depuis l'application utilise un contrôleur frontal, un conteneur de DI est créé là. Il crée ensuite un objet de routage, etc.

  • À la lumière de cela, dois-je passer une référence de ce conteneur vers le bas à l'objet loginController, et ensuite utiliser ce conteneur pour instancier mon adaptateur? Ou est-ce que je devrais instancier un nouveau conteneur dans mon objet loginController et charger juste dans une instance de l'adapteur?

Répondre

2

Je ferais le premier: passer une référence à votre contrôleur. Vous devez utiliser un seul conteneur d'injecteur de dépendance (DIC) dans votre application. Vous ne voulez pas créer un nouveau DIC chaque fois que vous avez besoin d'y accéder. Cela conduirait à la duplication des objets stockés dans le DIC. Je sais que c'est comme cela que Symfony 2 le fait. Tous les contrôleurs (et de nombreuses autres classes) implémentent l'interface ContainerAware. Cette interface a une seule méthode setContainer() qui est utilisée pour transmettre une référence au DIC.

+0

Merci :) J'ai créé une classe abstraite similaire à ContainerAware que d'autres classes peuvent étendre.Le conteneur lui-même est ensuite automatiquement injecté dans cette classe au moment de l'exécution. Cela semble être beaucoup plus propre. – F21

2

Je ne connais pas votre outil DI spécifique, mais d'un point de vue DI, vous spécifieriez le type à utiliser. Le conteneur lui-même est responsable de l'instanciation d'une nouvelle instance (et éventuellement de toutes les dépendances de ce type) du type configuré. L'avantage de DI dans votre exemple est que vous pouvez déployer exactement le même code avec une configuration différente avec 1 installation utilisant LDAP et l'autre utilisant l'authentification MySQL.

1

Afficheur de type réflecteur ("AbstractLoginAdapter") à ("MySQLLoginAdapter").

Si vous appelez la méthode de classe abstraite dans le nouveau __CLASS__ // Fatal Error.