Как я могу получить доступ к услуге за пределами контроллера с Symfony2? - PullRequest
51 голосов
/ 25 мая 2011

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

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

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

Ответы [ 2 ]

74 голосов
/ 25 мая 2011

Дистрибутив 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, но вы должны быть в состоянии понять их довольно легко.

  1. Официальный DI Symfony
  2. Статьи Фабьена Потенциера о DI
  3. Статьи Ричарда Миллера о DI (Проверьте в своем блоге другие статьи о DI)

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

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

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

0 голосов
/ 24 декабря 2013

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...