Как правильно работать с зависимостями в контроллере? Есть сущность class Company { private $name; public function __construct($name) {
$this->name = $name; } } я хочу сохранить её interface RepositoryInterface {
public function add(Company $company): void;
} class MySqlRepository implements RepositoryInterface { private $db; public function __construct(DbConnection $db) { $this->db = $db; } public function add(Company $company): void { $name = $company->name; $stmt = $this->db->prepare("INSERT INTO company (name) VALUES $name"); $stmt->execute(); } } с помощью сервиса class CompanyService { private $repository; public function __construct(RepositoryInterface $repository) { $this->repository = $repository; } public function createCompany($dto): void { $this->repository->add($dto); } } Ну и контроллерclass Controller { private $service; public function __construct(CompanyService $service) {
$this->service = $service; }
public function actionCreate() { //* получаем dto из формы $dto; $this->service->createCompany($dto); } } Правильно я понимаю, что мне придется пробрасывать везде:$db = new DbConnection('127.0.0.1', 'root', 'dbname', ''); $repository = new MySqlRepository($db); $service = new CompanyService($repository); И как то передавать это в контроллер с которым я работаю? Ведь у сервиса в конструкторе репозиторий, у репозитория в конструкторе подключение к базе данных? Это должно как то создаваться в конструкторе контроллера? class Controller { private $service; /** Где это должно быть? */ $db = new DbConnection('127.0.0.1', 'root', 'dbname', ''); $repository = new MySqlRepository($db); $service = new CompanyService($repository); */// public function __construct(CompanyService $service) {
$this->service = $service; }
public function actionCreate() { //* получаем dto из формы $dto; $this->service->createCompany($dto); } } Как правильно это делается по ООП?
В данном случае, правильным подходом к работе с зависимостями было бы использование паттерна Dependency Injection (внедрение зависимостей).
Для этого необходимо создать объекты DbConnection, MySqlRepository и CompanyService внутри контейнера зависимостей (например, с помощью специализированных библиотек типа Symfony DI Container или создать собственный контейнер зависимостей).
Пример создания объектов в контейнере зависимостей:
$db = new DbConnection('127.0.0.1', 'root', 'dbname', ''); $repository = new MySqlRepository($db); $service = new CompanyService($repository);
Затем передаем этот контейнер в конструктор контроллера и используем объекты из него:
class Controller { private $service; public function __construct(Container $container) { $this->service = $container->getService('CompanyService'); } public function actionCreate() { // Получаем dto из формы $dto; $this->service->createCompany($dto); } }
Контейнер зависимостей обеспечит правильное создание и внедрение объектов в нужные места вашего приложения, что позволит избежать жесткой завязки классов друг на друга и упростит тестирование и сопровождение кода.
В данном случае, правильным подходом к работе с зависимостями было бы использование паттерна Dependency Injection (внедрение зависимостей).
Для этого необходимо создать объекты DbConnection, MySqlRepository и CompanyService внутри контейнера зависимостей (например, с помощью специализированных библиотек типа Symfony DI Container или создать собственный контейнер зависимостей).
Пример создания объектов в контейнере зависимостей:
$db = new DbConnection('127.0.0.1', 'root', 'dbname', '');$repository = new MySqlRepository($db);
$service = new CompanyService($repository);
Затем передаем этот контейнер в конструктор контроллера и используем объекты из него:
class Controller {private $service;
public function __construct(Container $container) {
$this->service = $container->getService('CompanyService');
}
public function actionCreate() {
// Получаем dto из формы
$dto;
$this->service->createCompany($dto);
}
}
Контейнер зависимостей обеспечит правильное создание и внедрение объектов в нужные места вашего приложения, что позволит избежать жесткой завязки классов друг на друга и упростит тестирование и сопровождение кода.