开发者

How to work with dependency injection within SOA?

I'm currently using SOA, I've a bunch of Service, (ArticleService, CommentService, UserService, etc..)

I also 开发者_运维技巧have a ConfigurationService which is filled from an XML configuration file.

I'm using Zend Framework.

THis configuration service is needed in some of my service, and I'm using dependency injection, is it a good practice, to add ConfigurationService in constructor of most my Service to be able to fetch global configuration?

Thank you for your feedbacks.


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. ;-)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜