我在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?
答案 0 :(得分:1)
我过去使用Pimple(由Symfony的所有者Fabien Potencier创建)实现了这一目标。
Pimple是PHP 5.3的一个小型依赖注入容器,它只包含一个文件和一个类(大约50行代码)。
以下是我将其与我的ZF1应用程序相结合的方法:
如果您的服务声明得很好(通过构造函数注入依赖项),则不必访问控制器或CLI工具之外的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();
}
}
为了将DIC用于CLI工具:
Zend_Application
以创建CLI应用程序run()
以阻止MVC堆栈引导使用基本命令类通过$this->container
轻松访问DIC:
abstract class MyApp_Command
{
protected $container;
public function __construct($container)
{
$this->container = $container;
}
}
答案 1 :(得分: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()
。您可以访问引导程序中可用的所有方法。