1

我在 Zend Framework 项目中实现了 Symfony2 依赖注入容器,它在我的应用程序的 MVC 层中运行良好。我已经在我的引导程序中初始化了 DIC,并且可以通过调用在任何地方访问它:

Zend_Controller_Front::getInstance()->getParam('bootstrap')->getDic()

问题是我的应用程序的某些部分没有使用 Zend Framework 应用程序/MVC 层。例如我的 CLI 工具。我可以在那里完美地初始化一个新的 DIC,但这只是 Bootstrap 文件中的一些复制粘贴工作,这会在路上遇到麻烦(DRY 原则等)

例如,让我的 DIC 在Zend_Registry或作为静态方法调用的单例中可用是更好的解决方案DIC::getInstance()吗?

我知道注册表和单例被认为是坏事,但 DIC 是应用程序的高级部分,我可能永远不会遇到使其成为坏事的问题。

这是一个好的解决方案还是有更好的方法来实现全球可访问的 DIC?

4

2 回答 2

1

要访问 CLI 文件中的引导资源,您可以对应用程序进行部分引导

而不是这样做(public/index.php)并引导您的整个应用程序:

$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
            ->run();

您可以这样做,并且只引导所需的资源:

$app = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH .  '/configs/application.ini'
);

// Selectively bootstrap resources:
$app->bootstrap('db');
$app->bootstrap('log');
$app->bootstrap('autoload');
$app->bootstrap('config');
$app->bootstrap('di');

您必须确保以正确的顺序初始化它们(例如,如果您有一个用于日志的数据库写入器,您可能需要在日志记录组件之前加载您的数据库)。

从那里,您可以调用引导程序的一部分(对于 DI 组件,您可以调用$app->getBootstrap()->getContainer(). 您可以访问引导程序中所有可用的方法。

于 2012-09-04T15:26:55.527 回答
1

我过去使用Pimple(由 Symfony 的所有者 Fabien Potencier 创建)实现了这一点。

Pimple 是 PHP 5.3 的一个小型依赖注入容器,它只包含一个文件和一个类(大约 50 行代码)。

这是我如何将它与我的 ZF1 应用程序耦合的:

  1. 在应用程序的引导程序中创建一个新的 Pimple 容器
  2. 使用适当的依赖关系声明所有服务
  3. 通过控制器或 CLI 工具访问 DIC
  4. 通过 DIC 访问服务

如果您的服务声明良好(通过其构造函数注入依赖项),则您不必在控制器或 CLI 工具之外访问 DIC。

使用基本控制器类通过以下方式轻松访问 DIC $this->container

abstract class MyApp_Controller_Action extends Zend_Controller_Action
{
    protected $container;

    public function init()
    {
        $this->container = Zend_Controller_Front::getInstance()
                               ->getParam('bootstrap')->getDic();
    }
}

为了在 CLI 工具中使用您的 DIC:

  1. 扩展Zend_Application以创建您的 CLI 应用程序
  2. 覆盖run()以防止 MVC 堆栈引导
  3. 创建 CLI 工具时,通过其构造函数注入 DIC

使用基本命令类通过以下方式轻松访问 DIC $this->container

abstract class MyApp_Command
{
    protected $container;

    public function __construct($container)
    {
        $this->container = $container;
    }
}
于 2012-09-04T08:44:58.173 回答