Как работать с внедрением зависимостей в SOA? - PullRequest
3 голосов
/ 17 июня 2011

В настоящее время я использую SOA, у меня есть набор Service (ArticleService, CommentService, UserService и т. Д.)

У меня также есть ConfigurationService, который заполняется из файла конфигурации XML.

Я использую Zend Framework.

Этот сервис конфигурации необходим в некоторых моих сервисах, и я использую внедрение зависимостей, это хорошая практика, чтобы добавить ConfigurationService в конструктор большинствамой Сервис, чтобы можно было получить глобальную конфигурацию?

Спасибо за ваши отзывы.

1 Ответ

3 голосов
/ 17 июня 2011

Я бы сказал, нет, не передавайте контейнер конфигурации - ни как службу, ни как массив, ни как экземпляр Zend_Config - в конструктор других ваших служб. Я бы сохранил инъекцию (будь то конструктор или установщик) для тех сервисов, которые ориентированы на реальные объекты / соавторов / данные, которые им действительно нужны.

Так, например, ArticleService может зависеть от ArticleRepository интерфейса / объекта или от ArticleMapper или от адаптера БД. Пусть подписи конструктора / установщика для 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 или новый пакет Zend\Di в ZF2. Но после многих месяцев борьбы со всеми рекомендациями наилучшей практики для введения ваших зависимостей, это то, что я придумал. Если это глупо или просто неправильно, пожалуйста (пожалуйста!) Поправьте меня. ; -)

...