Ответ 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, но вы должны понимать их довольно легко.
- Symfony Official DI
- Статьи Fabien Potencier по DI
- Статьи Ричарда Миллера о DI (зайдите в его блог для других статей DI)
Обратите внимание, что конфигурация, которую я даю, работает для бета-версии Symfony2. Я еще не обновил Beta2, поэтому некоторые вещи могут не работать, как в версии Beta2.
Надеюсь, это поможет вам определить окончательное решение вашей проблемы. Не стесняйтесь задавать другие вопросы, если вам нужны разъяснения или что-то еще.
С уважением, Matt