Как я могу получить доступ к службе вне контроллера с Symfony2?


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

может кто-нибудь сказать мне, если это возможно, и если нет, есть ли предлагаемый подход к выполнению такого рода вещей?

спасибо за помощь

2 51

2 ответа:

распределение Symfony сильно зависит от инъекции зависимостей. Это означает, что, как правило, зависимостей вводятся непосредственно в ваш объект через конструктор, сеттеры или с помощью других средств (например, отражение свойств). Ваша служба оболочки API является зависимостью для других объектов вашего приложения.

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

что вы могли бы сделать, это создать другую службу, которая будет отвечать за выполнение работы, которую вы собирались сделать в репозитории сущностей. Таким образом, Вы сможете внедрить диспетчер сущностей, который будет использоваться для извлечения репозитория сущностей, пользовательской службы, а также другой службы, содержащей ваши значения конфигурации (есть и другие способы совместного использования значение конфигурации.)

в моем случае использования я использую вспомогательную службу Facebook, которая обертывает вызовы API Facebook. Эта услуга затем вводится там, где мне это нужно. Мой репозиторий сущностей отвечает только за выполнение вызовов базы данных, поэтому он получает только необходимые аргументы, а не всю зависимость. Таким образом, он не получит помощника, а только аргументы, необходимые для выполнения запроса, например, идентификатор пользователя Facebook. На мой взгляд, это способ сделать это, так как я думаю на лицо репозиторий не должен иметь зависимостей от таких вспомогательных объектов.

вот небольшой пример использования YAML в качестве конфигурации:

# app/config/config.yml
services:
  yourapp.configuration_container:
    class: Application/AcmeBundle/Common/ConfigurationContainer
    # You could inject configurations here      

  yourapp.api_wrapper:
    class: Application/AcmeBundle/Service/ApiWrapperService
    # Inject other arguments if needed and update constructor in consequence    

  yourapp.data_access:
    class: Application/AcmeBundle/Data/Access/DatabaseAccessService
    arguments: 
      entityManager: "@doctrine.orm.entity_manager"
      apiWrapperService: "@yourapp.api_wrapper"
      configuration: "@yourapp.configuration_container"

# Application/AcmeBundle/Common/ConfigurationContainer.php
public ConfigurationContainer
{
   public function __construct()
   {
       // Initialize your configuration values or inject them in the constructor
   }
}        

# Application/AcmeBundle/Service/ApiWrapperService.php
public ApiWrapperService
{
   public function __construct()
   {
       // Do some stuff
   }
}

# Application/AcmeBundle/Data/Access/DatabaseAccessService.php
public DatabaseAccessService
{
    public function __construct(EntityManager $entityManager, ApiWrapperService $apiWrapperService, ConfigurationContainer $configuration)
    {
        ...
    }
}

знак (@) в config.файл yml означает ,что Symfony должен вводить другую службу, имеющую идентификатор, определенный после знака at, а не простую строку. Для значений конфигурации, как я уже говорил ранее, есть другие средства для достижения той же цели, как с помощью параметров или расширения пакета. С расширением пакета вы можете определите значения конфигурации непосредственно в конфигурации.yml и ваш пакет будут читать их.

В заключение, это должно дать вам общее представление о инъекционных услуг. Вот небольшой перечень документации по данной теме. Многие ссылки используют определение службы XML вместо определения YAML, но вы должны быть в состоянии понять их довольно легко.

  1. Symfony Official DI
  2. С Fabien Potencier на Ди
  3. статьи Ричарда Миллера О Ди (проверьте в своем блоге для других статей DI)

обратите внимание, что конфигурация, которую я даю, работает для Beta1 из Symfony2. Я еще не обновился до Beta2, поэтому некоторые вещи могут не работать, поскольку они находятся в версии Beta2.

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

С уважением, Мэтт

Я бы обернул такое поведение в Службу Symfony (например, менеджер). я бы не стал вводить какие-либо параметры или логику в репозитории сущностей, поскольку они должны в основном использоваться для извлечения данных с помощью запросов диспетчера объектов. Я бы поместил логику в службы , и если служба требует доступа к базе данных, она вызовет репозиторий сущностей для извлечения данных.