How to work with dependency injection within SOA?

I would say, no, don't pass the config container - neither as a service nor as an array nor a Zend_Config instance - in the constructor of your other services. I would keep the injection (whether by constructor or by setter) for those services focused on the actual objects/collaborators/data they actually need So, for example, an ArticleService might depend upon an ArticleRepository interface/object or on an ArticleMapper or on a db adapter. Let the constructor/setter signatures for the ArticleService reflect what it truly needs Instead, what I would do is during Bootstrap create some kind of factory object - perhaps as an application resource - that accepts in its constructor your config data/object/service (or even better, the bootstrap instance itself, from which you could get, not just your config data, but also any application resources, like a db adapter, that were created during the bootstrap process).

Then write methods on your factory object that create/deliver the other services you need. Internally, the factory maintains a registry of already created services so that it can lazy-create instances where required A snippet of what I have in mind might be as follows: Bootstrap snippet: class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initFactory() { $factory = new My_Factory($this); return $factory; } } Then the 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'; } } Then in a controller, you could grab an ArticleService instance: 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 } } The upshot here is that each service explicitly identifies the collaborators it needs and the factory is a single place that takes care of creating/injecting all those collaborators Finally, I confess that I am just spitballing here. To me, this is essentially a rudimentary dependency injection container; in that sense, using a fully-featured DIC - perhaps the Symfony DIC or the new Zend\Di package in ZF2 - might be better.

But after many months of struggling with all the best-practice recommendations to inject your dependencies, this is what I have come up with. If it's goofy or just plain wrong, please (please! ) straighten me out.

;-).

I would say, no, don't pass the config container - neither as a service nor as an array nor a Zend_Config instance - in the constructor of your other services. I would keep the injection (whether by constructor or by setter) for those services focused on the actual objects/collaborators/data they actually need. So, for example, an ArticleService might depend upon an ArticleRepository interface/object or on an ArticleMapper or on a db adapter.

Let the constructor/setter signatures for the ArticleService reflect what it truly needs. Instead, what I would do is during Bootstrap, create some kind of factory object - perhaps as an application resource - that accepts in its constructor your config data/object/service (or even better, the bootstrap instance itself, from which you could get, not just your config data, but also any application resources, like a db adapter, that were created during the bootstrap process). Then write methods on your factory object that create/deliver the other services you need.

Internally, the factory maintains a registry of already created services so that it can lazy-create instances where required. A snippet of what I have in mind might be as follows: Bootstrap snippet: class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initFactory() { $factory = new My_Factory($this); return $factory; } } Then the 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'; } } Then in a controller, you could grab an ArticleService instance: 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 } } The upshot here is that each service explicitly identifies the collaborators it needs and the factory is a single place that takes care of creating/injecting all those collaborators. Finally, I confess that I am just spitballing here.To me, this is essentially a rudimentary dependency injection container; in that sense, using a fully-featured DIC - perhaps the Symfony DIC or the new Zend\Di package in ZF2 - might be better.

But after many months of struggling with all the best-practice recommendations to inject your dependencies, this is what I have come up with. If it's goofy or just plain wrong, please (please!) straighten me out. ;-).

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions