适配器和依赖注入

时间:2011-07-12 11:11:20

标签: php dependency-injection adapter

我目前正在用PHP构建一个MVC应用程序(不使用任何框架)。我使用yadif(https://github.com/beberlei/yadif)进行依赖注入。

我想构建一个登录模块。它应该能够使用适配器,例如,可以使用MySql数据库或某个LDAP目录设置登录验证。此设置将在管理区域中完成,并存储在数据库中。

我想我会有一个抽象的适配器:

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

然后我会像这样实现适配器:

<?php
MySQLLoginAdapter extends AbstractLoginAdapter{

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

这一切都很好,但我如何创建适配器的实例?通常,依赖项将通过构造函数使用yadif注入:

<?php
class loginController{

    private $_adapter;

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

但是,由于我不知道将注入哪个具体的适配器,我无法在配置之前设置它。 Yadif允许我创建一个配置,然后我需要传递给容器:

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

由于应用程序使用前端控制器,因此在那里创建了DI容器。然后它创建一个路由对象等。

  • 鉴于此,我应该将该容器的引用传递给loginController对象,然后使用该容器来实例化我的适配器吗?

  • 或者我应该在loginController对象中实例化一个新容器,然后只加载适配器的实例?

3 个答案:

答案 0 :(得分:2)

我不知道您的特定DI工具,但从DI的角度来看,您将指定要使用的类型。容器本身负责实例化配置类型的新实例(以及可能还包括该类型的所有依赖项)。

在您的示例中,DI的好处是您可以使用不同的配置部署完全相同的代码,其中1个使用LDAP安装,另一个使用MySQL身份验证。

答案 1 :(得分:2)

我会做第一个:将参考传递给你的控制器。您将需要在应用程序中使用单个依赖注入器容器(DIC)。您不希望在需要访问它时创建新的DIC。这将导致存储在DIC中的对象重复。

我知道Symfony 2就是这样做的。所有控制器(以及许多其他类)都实现ContainerAware接口。该接口有一个方法setContainer(),用于传递对DIC的引用。

答案 2 :(得分:1)

重构类型提示("AbstractLoginAdapter")("MySQLLoginAdapter")

如果在新__CLASS__ // Fatal Error中调用抽象类方法。