Symfony DI для событийных классов - PullRequest
0 голосов
/ 06 мая 2019

У меня есть некоторые события в моем проекте, который использует DI.Когда мои события являются экземпляром App \ Manager \ ValidatorAwareInterface, я настраиваю их для добавления службы @validator.

Когда у меня есть этот код в services.yaml, он работает:

services:
    _instanceof:
        App\Manager\Validator\ValidatorAwareInterface:
            calls:
                -   method: setValidator
                    arguments:
                        - '@validator'

Но когда я помещаю этот же код в файл manager.yaml, который импортирую в services.yaml, он больше не работает:

imports:
    - { resource: manager.yaml }

У вас есть идея, почему?

Спасибо.

Ответы [ 2 ]

1 голос
/ 06 мая 2019
Ответ * 1000000@stephan.mada, вероятно, решит вашу проблему.

Но я хотел бы отметить небольшую известную аннотацию под названием «@required», которая устраняет необходимость вообще явно настраивать ваш установщик.

use Symfony\Component\Validator\Validator\ValidatorInterface;

trait ValidatorTrait
{
    /** @var ValidatorInterface */
    protected $validator;

    /** @required */
    public function injectValidator(ValidatorInterface $validator)
    {
        $this->validator = $this->validator ?: $validator;
    }
}

@required перед методом внедрения заставляет контейнер автоматически внедрять зависимость. Ваш сеттер в services.yaml может полностью исчезнуть. Вы не видите много случаев использования «@required», но он пригодится для часто внедряемых сервисов.

Вы также можете заметить, что я использовал здесь черту. С чертой мне больше не нужен базовый класс или интерфейс. Любой сервис, который использует эту черту, автоматически получает сервис валидатора. Вы можете, конечно, просто использовать обычный класс, если хотите.

class SomeService
{
    use ValidatorTrait; // And the validator is now available
    use RouterTrait;    // As well as the router

И последнее замечание. Я добавил защиту, чтобы гарантировать, что валидатор может быть введен только один раз. Это защищает от мошеннических программистов, у которых может возникнуть соблазн ввести другой валидатор в какой-то другой точке цикла.

1 голос
/ 06 мая 2019

Я думаю, вам следует скопировать конфигурацию службы по умолчанию в symfony в вашем manager.yaml перед определением других служб, поскольку конфигурация по умолчанию применяется только к службам, определенным в этом файле. Новый файл default.yaml по умолчанию

# config/manager.yaml
services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        public: false       # Allows optimizing the container by removing unused services; this also means
                            # fetching services directly from the container via $container->get() won't work.
                            # The best practice is to be explicit about your dependencies anyway.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{Entity,Migrations,Tests}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']

    # add more service definitions when explicit configuration is needed
    # please note that last definitions always *replace* previous ones

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