Подтвердить что ты не робот

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

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

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

спасибо за любую помощь

4b9b3361

Ответ 1

Распределение 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)
    {
        ...
    }
}

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

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

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

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

С уважением, Matt

Ответ 2

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