Правильно ли использовать подобный сервис в Symfony 3.4?

Так можно ли это использовать или лучше внедрить службу в конструктор контроллера? Я знаю, что есть способ получше, но можно ли ради лени?

class someController extends Controller 
{
    /**
     * @Route("/test")
     */
    public function someFunction() 
    {
        $manager = $this->getDoctrine();
        $service = new someService($manager);

        $all =  $service->getAll();
        dump($all);exit;
    }
}


------------------------------------------------
use Doctrine\Common\Persistence\ManagerRegistry;

class someService implements someServiceInterface 
{
   /**
    * @var ManagerRegistry
    */
    private $manager;

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

    public function getAll() 
    {
        return $this->manager->getRepository(SomeEntity::class)->findAll();
    }
}

Лучше колоть. Это не совсем сложно, правда? Вы, наверное, приложили больше усилий для создания этого вопроса, чем для того, чтобы просто сделать это :)

Jonnix 20.12.2018 16:11

Можно, но это противоречит принципам SOLID.

Felippe Duarte 20.12.2018 16:13

Короткий ответ: нет. Ваш сервис на самом деле не является сервисом с точки зрения Symfony, учитывая, что он не вводится напрямую через конструктор вашего контроллера (или метод действия).

Nek 20.12.2018 16:13
Стоит ли изучать 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
3
98
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете внедрить свою службу прямо в контроллер, используя

public function someFunction(someService $service) //I do that because I'm lazier than you.
{
    //your code
}

auto-wiring будет искать вашу услугу и вводить ее.

В services.yaml вы можете установить:

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

Более подробную информацию об автоматическом подключении можно найти в документация.

Хотя это и не неверно (ваше приложение не выйдет из строя), это не рекомендуется. Предлагаю вам прочитать это страница

Как вы уже догадались, вы можете внедрить свой сервис в свой конструктор. Просто включите его в своем config.yml, добавив

App\Controller\:
    resource: '../../Controller'
    tags: ['controller.service_arguments']

Это решит вам массу хлопот и проведет рефакторинг, когда вашему сервису понадобится другая зависимость.

class SomeController extends AbstractController // Controller deprecated since 4.0
{
    /**
     * @Route("/test")
     */
    public function someFunction(SomeServiceInterface $someService) // that's all what you need, "autowire: true" by default since 3.4
    {
        $manager = $this->getDoctrine();
        $all =  $someService->getAll();
        dump($all);exit;
    }
}


------------------------------------------------
use Doctrine\Common\Persistence\ManagerRegistry;

class SomeService implements SomeServiceInterface
{
    /**
     * @var ManagerRegistry
     */
    private $manager;

    public function __construct(ManagerRegistry $manager) // autowire
    {
        $this->manager = $manager;
    }

    public function getAll()
    {
        return $this->manager->getRepository(SomeEntity::class)->findAll();
    }
}
Ответ принят как подходящий

Я предполагаю, что у вас проблемы с вашим сервисом, потому что вам нужно ввести диспетчер сущностей внутрь. Обратите внимание, что в этом нет ничего плохого. Вот код, который должен работать:

Допустим, мы внедряем сервис:

// Better use camel case with upper first letter
class SomeController extends Controller 
{    
    /**
     * @Route("/test")
     */
    public function someFunction(SomeService $someService) 
    {
        $all =  $someService->getAll();
        dump($all);exit;
    }
}

Вы можете ввести прямо в конструктор вашего контроллера, но здесь я использую инъекцию действия, см. документацию.

Вот как выглядят ваши услуги:

class SomeService implements SomeServiceInterface 
{
   /**
    * @var EntityManagerInterface
    */
    private $manager;

    // Type hinting matters here!
    public function __construct(EntityManagerInterface $manager)
    {
        $this->manager = $manager;
    }

    public function getAll() 
    {
        return $this->manager->getRepository(SomeEntity::class)->findAll();
    }
}

Это работает из коробки в настройках Symfony 4.x, потому что они по умолчанию определяют автозагрузку и автосоединение сервисов. Какие функции доступны в Symfony 3.4, см. документацию.

Но для того, чтобы все это настроить вручную, вам может понадобиться такая конфигурация:

You\SomeController:
    autowire: true
    tags: ['controller.service_arguments']
You\SomeService:
    autowire: true

Наконец, если вы ищете способ делать ленивые сервисы, это особенность компонента внедрения зависимостей в Symfony. См. Снова документация здесь.

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