#symfony
#symfony
Вопрос:
Я пытаюсь использовать метод-return-value в качестве параметра DI. Конкретный вариант использования заключается в том, что у меня есть сервис, который имеет логику вычисления кода страны пользователя, например:
$user->getCountryCode();
С другой стороны, у меня есть много сервисов, которые зависят от страны, например:
$foo = new Foo('UK');
$bar = new Bar('USA');
Я знаю, что могу ввести пользовательский сервис в Foo / Bar, но это создает странную зависимость, поскольку этим службам не нужен пользователь, им просто нужен код страны.
Есть ли у меня способ написать описание сервиса в соответствии с:
my_services.foo:
class: Foo
arguments:
- @user.getCountryCode
Редактировать:
Я использую symfony 2.4 с конфигурацией yml.
Ответ №1:
Метод фабрики сервисов (совместим со всеми версиями Symfony2)
Определения служб:
# services.yml
FooFactory:
class: FooFooBundleServiceFooFactory
arguments: [@user_country_code_calc_service]
FooService:
class: FooFooBundleServiceFooService
factory_service: FooFactory
factory_method: create
И ваша фабрика:
// FooFactory.php
class FooFactory
{
private $countryCodeCalculator;
public function __construct(UserCountryCodeCalculator $countryCodeCalculator)
{
$this->countryCodeCalculator = $countryCodeCalculator;
}
public function create()
{
$countryCode = $this->countryCodeCalculator->calculate(...);
return new FooService($countryCode);
}
}
Теперь, когда вы вводите @FooFactory
любой из своих сервисов, Symfony фактически вызовет FooFactory::create
и введет в него результат этого метода.
Ответ №2:
Метод языка выражений (совместим с версиями Symfony> = 2.4)
# services.yml
foo_service:
class: FooFooBundleServiceFooService
arguments: ["=service('user_countrycode_calc_service').calculateCountryCode()"]
Комментарии:
1. Это не позволит мне вводить «скалярные» значения, поскольку для службы требуется допустимый класс.
2. удалить
@
из начала аргумента, я допустил опечатку3. На самом деле
@
это необходимо (как показано в документации ). Я лично использую его только для включения метода MasterRequest ("GET"
/"POST"
..), и он работает :"@=service('request_stack').getMasterRequest().getMethod()"