Я перемещаю проект Symfony 3.2 в Symfony 3.3 и хочу использовать Новые функции DI. Я прочитал документацию, но пока могу заставить это работать. См. следующее определение класса:
use Http\Adapter\Guzzle6\Client;
use Http\Message\MessageFactory;
abstract class AParent
{
protected $message;
protected $client;
protected $api_count_url;
public function __construct(MessageFactory $message, Client $client, string $api_count_url)
{
$this->message = $message;
$this->client = $client;
$this->api_count_url = $api_count_url;
}
public function getCount(string $source, string $object, MessageFactory $messageFactory, Client $client): ?array
{
// .....
}
abstract public function execute(string $source, string $object, int $qty, int $company_id): array;
abstract protected function processDataFromApi(array $entities, int $company_id): array;
abstract protected function executeResponse(array $rows = [], int $company_id): array;
}
class AChildren extends AParent
{
protected $qty;
public function execute(string $source, string $object, int $qty, int $company_id): array
{
$url = $this->api_count_url . "src={$source}&obj={$object}";
$request = $this->message->createRequest('GET', $url);
$response = $this->client->sendRequest($request);
}
protected function processDataFromApi(array $entities, int $company_id): array
{
// ....
}
protected function executeResponse(array $rows = [], int $company_id): array
{
// ....
}
}
Вот как выглядит мой файл app/config/services.yml
:
parameters:
serv_api_base_url: 'https://url.com/api/'
services:
_defaults:
autowire: true
autoconfigure: true
public: false
CommonBundle\:
resource: '../../src/CommonBundle/*'
exclude: '../../src/CommonBundle/{Entity,Repository}'
CommonBundle\Controller\:
resource: '../../src/CommonBundle/Controller'
public: true
tags: ['controller.service_arguments']
# Services that need manually wiring: API related
CommonBundle\API\AParent:
arguments:
$api_count_url: '%serv_api_base_url%'
Но я получаю следующую ошибку:
AutowiringFailedException Не удается выполнить автоподключение сервиса "CommonBundle\API\AChildren": аргумент "$api_count_url" метода "__construct()" должен иметь подсказку типа или иметь явное значение.
Конечно, я что-то здесь упускаю или просто это невозможно, что приводит меня к следующему вопросу: это плохой дизайн ООП или недостающая функциональность в функциях Symfony 3.3 DI?
Конечно, я не хочу делать класс AParent
интерфейсом, поскольку я не хочу переопределять методы классов, реализующих такой интерфейс.
Также я не хочу повторяться и копировать/вставлять одни и те же функции во всех дочерних элементах.
Идеи? Подсказки? Совет? Это возможно?
ОБНОВЛЕНИЕ
После прочтения "Как управлять общими зависимостями с родительскими службами" я попробовал в моем сценарии:
CommonBundle\API\AParent:
abstract: true
arguments:
$api_count_url: '%serv_api_base_url%'
CommonBundle\API\AChildren:
parent: CommonBundle\API\AParent
arguments:
$base_url: '%serv_api_base_url%'
$base_response_url: '%serv_api_base_response_url%'
Но ошибка превращается в:
Атрибут "autowire" в службе "CommonBundle\API\AChildren" не может быть унаследован от "_defaults", если установлен "родительский". Переместите свои дочерние определения в отдельный файл или явно определите этот атрибут в /var/www/html/oneview_symfony/app/config/services.yml (который импортируется из "/var/www/html/oneview_symfony/app/config/ config.yml").
Однако я мог заставить его работать со следующей настройкой:
CommonBundle\API\AParent:
arguments:
$api_count_url: '%serv_api_base_url%'
CommonBundle\API\AChildren:
arguments:
$api_count_url: '%serv_api_base_url%'
$base_url: '%serv_api_base_url%'
$base_response_url: '%serv_api_base_response_url%'
Это правильный путь? Имеет ли это смысл?
ОБНОВЛЕНИЕ №2
Следуя инструкциям @Cerad, я сделал несколько модов (см. код выше и определение ниже), и теперь объекты приходят NULL
? Есть идеи, почему так?
// services.yml
services:
CommonBundle\EventListener\EntitySuscriber:
tags:
- { name: doctrine.event_subscriber, connection: default}
CommonBundle\API\AParent:
abstract: true
arguments:
- '@httplug.message_factory'
- '@httplug.client.myclient'
- '%ser_api_base_url%'
// services_api.yml
services:
CommonBundle\API\AChildren:
parent: CommonBundle\API\AParent
arguments:
$base_url: '%serv_api_base_url%'
$base_response_url: '%serv_api_base_response_url%'
// config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
- { resource: services_api.yml }
Почему объекты NULL
в дочернем классе?