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






Поскольку определенный конструктор используется для доставки данных в заданиях в 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();
}
}
Если ваша очередь была настроена на использование Laravel очередь заданий, вы, вероятно, могли бы передать как зависимости, так и аргументы через конструктор (согласно документации на автоматический впрыск), но я не пробовал этого, извините. Вы также знакомы со вспомогательным методом
resolve()? Вы можете вызвать это из своего абстрактного конструктора, чтобы настроить свои зависимости.