Служба (использует фабрику служб) для возврата объектов разных типов.

Мне нужно создать службу, которая использует другую фабричную службу и возвращает объекты разных типов.
Вот определения моих служб:

services:
    games.search_factory:
        class: %games.search_factory.class%
        calls:
           - [ setContainer, ["@service_container"] ]

    games.search:
        class: %games.search.base.class%
        factory_service: games.search_factory
        factory_method: get

Мой метод %games.search_factory.class% get возвращает разные объекты в зависимости от параметров запроса.
Мой %games.search.base.class% является абстрактным.
Моя цель - когда я вызываю

$this->get("games.search");  

Я хочу получить результат фабричного метода. Но когда я запускаю код, я получаю сообщение об ошибке: FatalErrorException: Ошибка: невозможно создать экземпляр абстрактного класса.

Итак, у меня есть два вопроса:

  1. Почему система DI пытается создать экземпляр моего класса вместо того, чтобы возвращать результат моего фабричного метода?
  2. Есть ли способ реализовать то, что мне нужно (красиво и лаконично)?

Обновление: у меня была ошибка в части кода, которая здесь не показана. Помимо этих двух сервисов для поиска, у меня был сервис для каждого типа поиска, и эти сервисы я вернул с завода. Но в определении этих сервисов я использовал свой базовый класс (который является абстрактным) в качестве класса.

Хороший вывод: из фабрики можно возвращать объекты разных типов.


person Vitaliy Lebedev    schedule 26.03.2013    source источник


Ответы (1)


Отсюда: http://symfony.com/doc/current/components/dependency_injection/factories.html

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

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

person Cerad    schedule 26.03.2013
comment
Но моя фабрика имеет возможность создания экземпляров. И я сделал именно то, что говорит документ: я настроил свою фабрику как отдельную службу, чтобы она могла принимать параметр контейнера. Проблема в том, что когда я использую эту фабрику для получения экземпляров службы games.search, я получаю не результат метода get фабрики, а новый экземпляр %games.search.base.class%, мне - person Vitaliy Lebedev; 27.03.2013
comment
Ok. Начните отладку, поместив операторы die в конструктор фабрики и в factory.get. Я предполагаю, что ваша фабрика неправильно считывает параметры маршрута и в результате возвращает класс по умолчанию. Если штамп вызывается, пожалуйста, опубликуйте свой заводской код. - person Cerad; 27.03.2013
comment
Спасибо, ваш совет очень помог! Я нашел ошибку в коде. Идея заключалась в том, чтобы вернуть услуги с моего завода (каждый поиск — это услуга). Но в определении каждой службы я просто скопировал базовый класс в качестве каждого класса служб (и этот класс является абстрактным). - person Vitaliy Lebedev; 27.03.2013
comment
Просто предложение: возможно, вы захотите посмотреть, сможете ли вы заменить контейнер конкретными службами, такими как request. Инъекция контейнера часто является излишним для таких вещей. - person Cerad; 27.03.2013