我目前正在使用面向服务架构,我有一堆服务(ArticleService、CommentService、UserService等)。
我还有一个从XML配置文件填充的ConfigurationService。
我使用的是Zend框架。
我的一些服务需要THis配置服务,而我正在使用依赖注入,在大多数我的服务的构造函数中添加ConfigurationService以获取全局配置是一种好的做法吗?
感谢您的反馈。
发布于 2011-06-17 06:18:26
我会说,不,不要在其他服务的构造函数中传递配置容器-既不作为服务,也不作为数组或Zend_Config
实例。我会将这些服务的注入(无论是通过构造函数还是通过setter)集中在它们实际需要的实际对象/协作者/数据上。
因此,例如,ArticleService
可能依赖于ArticleRepository
接口/对象,或者依赖于ArticleMapper
或db适配器。让ArticleService
的构造函数/设置器签名反映它真正需要的东西。
相反,我要做的是在Bootstrap
期间创建某种工厂对象--可能是作为应用程序资源--它在其构造函数中接受配置数据/对象/服务(或者更好的是引导实例本身,您不仅可以从引导实例中获取配置数据,还可以获取在引导过程中创建的任何应用程序资源,比如数据库适配器)。然后在您的工厂对象上编写方法,以创建/交付您需要的其他服务。在内部,工厂维护一个已经创建的服务的注册表,以便可以在需要的地方延迟创建实例。
我脑海中的一小段可能是:
引导程序代码片段:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initFactory()
{
$factory = new My_Factory($this);
return $factory;
}
}
然后工厂:
class My_Factory
{
protected $_registry;
protected $_bootstrap;
public function __constructor($bootstrap)
{
$this->_bootstrap = $bootstrap;
}
public function getDbAdapter()
{
if (!isset($this->_registry['dbAdapter']){
$this->_bootstrap->bootstrap('db'); // probably using app resource
$this->_registry['dbAdapter'] = $This->_bootstrap->getResource('db');
}
return $this->_registry['dbAdapter'];
}
public function getArticleService()
{
if (!isset($this->_registry['articleService']){
$dbAdapter = $this->getDbAdapter();
$this->_registry['articleService'] = new My_ArticleService($dbAdapter);
}
return $this->_registry['articleService'];
}
public function getTwitterService()
{
if (!isset($this->_registry['twitterService']){
$options = $this->_bootstrap->getOptions();
$user = $options['twitter']['user'];
$pass = $options['twitter']['pass'];
$this->_registry['twitterService'] = new My_TwitterService($user, $pass);
}
return $this->_registry['twitterService'];
}
}
然后在控制器中,您可以获取一个ArticleService
实例:
class SomeController extends Zend_Controller_Action
{
protected $_factory;
public function init()
{
$this->_factory = $this->getInvokeArg('bootstrap')->getResource('factory');
}
public function someAction()
{
$articleService = $this->_factory->getArticleService();
$this->view->articles = $articleService->getRecentArticles(5); // for example
}
}
这里的结果是,每个服务都显式地标识它需要的协作者,而工厂是一个单独的位置,负责创建/注入所有这些协作者。
最后,我承认我只是在这里吐口水。对我来说,这本质上是一个基本的依赖注入容器;从这个意义上说,使用功能齐全的DIC -可能是Symfony DIC或ZF2中的新Zend\Di
包-可能更好。但经过几个月的努力,我得到了注入依赖项的所有最佳实践建议,以下是我提出的建议。如果这是愚蠢的或者是完全错误的,请(请!)帮我拉直身子。;-)
https://stackoverflow.com/questions/6378160
复制相似问题