[Laravel]: Как мне внедрить зависимость в абстрактный класс, расширенный другими классами (заданиями)

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

В Laravel работа заданий заключается в том, что конструктор принимает любые значения, с помощью которых вы запускаете задание, а в методе обработчика зависимости могут быть введены, например:

class SomeJob extends Job implements ShouldQueue
{
    public function __construct(array $someData, int $someMoreData)
    {
        $this->someData     = $someData;
        $this->someMoreData = $someMoreData;
    }

    public function handle()
    {
        // Do something...
    }
}


\Queue::pushOn(Queue::getDefaultQueue(), new SomeJob([1, 2, 3], 4));

Это означает, что я не могу просто передать зависимости в абстрактный класс из конструктора расширяющегося класса. Единственный способ обойти это, как я вижу, - это иметь свойство в абстрактном классе, а затем устанавливать его в методе обработчика расширенного класса.

abstract class SomeAbstractClass extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    protected $configOne;
    protected $configTwo;
    protected $userRepository;

    public function __construct()
    {
        $this->configOne = config('someConfig.valueOne');
        $this->configTwo = config('someConfig.valueTwo');
    }

    public function doSomethingWithUserRepository()
    {
        return $this->userRepository->doSomething();
    }
}

class SomeClass extends SomeAbstractClass
{
    public function __construct(array $someData, int $someMoreData)
    {
        parent::__construct();

        $this->someData     = $someData;
        $this->someMoreData = $someMoreData;
    }

    public function handle(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }
}

Это работает так, как задумано, но не кажется правильным. Это кажется немного взломанным, даже если это работает. Есть ли способ обойти это? Это должно быть довольно распространенная проблема, также за пределами Laravel.

Если ваша очередь была настроена на использование Laravel очередь заданий, вы, вероятно, могли бы передать как зависимости, так и аргументы через конструктор (согласно документации на автоматический впрыск), но я не пробовал этого, извините. Вы также знакомы со вспомогательным методом resolve()? Вы можете вызвать это из своего абстрактного конструктора, чтобы настроить свои зависимости.

alexkb 03.09.2018 14:46

Спасибо за комментарий. Я не знал о методе разрешения, но, поскольку я использую 5.2, я не могу его использовать. Но, возможно, я смогу сделать что-то похожее на то, что он делает. Я буду смотреть в него. Спасибо. Вопрос все еще открыт для квалифицированного ответа.

Severin 03.09.2018 16:06
Стоит ли изучать 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 и хотите разрабатывать...
1
2
864
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку определенный конструктор используется для доставки данных в заданиях в Laravel, поэтому в этом случае вы должны рассматривать handle() как метод «конструктора».

Итак, рассмотрим этот пример:

<?php
abstract class SomeAbstractClass extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    protected $configOne;
    protected $configTwo;
    protected $userRepository;

    public function __construct()
    {
        $this->configOne = config('someConfig.valueOne');
        $this->configTwo = config('someConfig.valueTwo');
    }

    public function handle(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    protected function doSomethingWithUserRepository()
    {
        return $this->userRepository->doSomething();
    }
}

class SomeClass extends SomeAbstractClass
{
    public function __construct(array $someData, int $someMoreData)
    {
        parent::__construct();
        $this->someData     = $someData;
        $this->someMoreData = $someMoreData;
    }

    public function handle(UserRepository $userRepository)
    {
        parent::handle($userRepository);

        // you can do whatever you liiike
        $this->doSomethingWithUserRepository();
    }
}

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