Symfony: установите свойство "public" в "services.yaml" для всех классов в выбранном каталоге

Я хотел бы иметь возможность создавать сервисы по их именам классов. Один из способов сделать это: установить свойство "public" в "services.yaml" НО Я НЕ ХОЧУ устанавливать "общедоступное" свойство для ВСЕХ классов в моем проекте.

services.yaml

services:
  _defaults:
    public: false      # it helps to optimize performance, doesn't it?

App\Service\Service1
  public: true

App\Service\Service2
  public: true

App\Service\Service3
  public: true

  App\Service\*       # why I can't use something like "*" here ???
    public: true

Service1.php

namespace App\Service;
class Service1 
{
  // important: every service can have one or more dependencies (Foo, Bar, Baz ... etc)
  public function __construct(Foo $foo, Bar $bar)
  {
    $this->foo = $foo;
    //..........
  }
}

MyController.php

public function __construct(ContainerInterface $container) 
{
  $this->container = $container;
}

// hier $className is any class name like "App/Service/xxxx"
public function myAction (string $className) 
{
  return $this->container->get($className);
}

Вопросов:

  • есть ли способ установить "общедоступное" свойство для каталога?
  • есть ли лучший способ создать экземпляр службы по имени класса?

Спасибо

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
35
2

Ответы 2

Зачем вам нужно делать публичные сервисы? Это идет вразрез с лучшими практиками Symfony, которые препятствуют прямому извлечению сервисов из контейнера.

Если вы хотите определить службы, названные по имени их класса, достаточно указать на них:

services:
    App\Service\Service1: ~
    App\Service\Service2: ~
    App\Service\Service3: ~

    App\Service\Service4:
        arguments:
            - '@App\Service\Service1'
            - '@App\Service\Service2'
            - '@App\Service\Service3'

а затем вводите их напрямую в контроллеры, вместо использования контейнера.

Спасибо, Эди. Не могли бы вы написать, почему я могу «закачивать их в свои контроллеры напрямую»?

Alex Lysenko 30.03.2021 17:07

Моя проблема: я не хочу менять services.yaml каждый раз, когда добавляю новую службу

Alex Lysenko 30.03.2021 17:12

@AlexLysenko Вы можете использовать автоматическое подключение для своих сервисов, чтобы не определять свои сервисы вручную: symfony.com/doc/current/service_container/autowiring.html

Edi Modrić 30.03.2021 18:38

Возможно, вы сможете использовать функции импорта YAML, чтобы обобщить нужную вам конфигурацию и упростить ее обслуживание.

Например:

# /config/services.yaml
imports:
    - { resource: 'services/public/*.yaml' } # Import public services
    - { resource: 'services/private/*.yaml' } # Import private services

Хотя, как уже упоминалось, принуждение контейнерных сервисов к публичному использованию идет вразрез с соглашениями Symfony и не будет поддерживаться в будущих версиях. Используйте внедрение зависимостей вместо прямого взаимодействия с сервисным контейнером.

Другие вопросы по теме