Так можно ли это использовать или лучше внедрить службу в конструктор контроллера? Я знаю, что есть способ получше, но можно ли ради лени?
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();
}
}
Можно, но это противоречит принципам SOLID.
Короткий ответ: нет. Ваш сервис на самом деле не является сервисом с точки зрения Symfony, учитывая, что он не вводится напрямую через конструктор вашего контроллера (или метод действия).






Вы можете внедрить свою службу прямо в контроллер, используя
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. См. Снова документация здесь.
Лучше колоть. Это не совсем сложно, правда? Вы, наверное, приложили больше усилий для создания этого вопроса, чем для того, чтобы просто сделать это :)