Здравствуйте!
Осваиваю технику инверсии контроля. Не могу разобраться с парой вещей.
PaymentsComponent кладёт в очередь таск RequestJob.
RequestJob делает curl запросы через библиотеку Curl. Один инстанс библиотеки Curl создаётся для одного запроса (он имеет состояния).
Объясните, пожалуйста, как получать инстанс класса Curl в объекте RequestJob.
DI и библиотеки
Re: DI и библиотеки
Никак. Вместо этого разделяйте код на саму структуру Job с данными для помещения в очередь:wolfandman писал(а): ↑2020.09.24, 16:40 Объясните, пожалуйста, как получать инстанс класса Curl в объекте RequestJob.
Код: Выделить всё
class RequestJob
{
public string $url;
public function __construct(string $url)
{
$this->url = $url;
}
}
Код: Выделить всё
class RequestJobHandler
{
private HttpClient $client;
public function __construct(HttpClient $client)
{
$this->client = $client;
}
public function __invoke(RequestJob $job): void
{
$response = $this->client->get($job->url);
// ...
}
}
Код: Выделить всё
class Consumer
{
private ContainerInterface $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function consume(object $job): void
{
$handler = $this->resolveHandler($job);
$handler($job);
}
private function resolveHandler(object $job): callable
{
$name = get_class($job) . 'Handler';
return $this->container->get($name);
}
}
Re: DI и библиотеки
Если рассматривать yii2-queue, то можно для этого все свои Job-ы с данными:
просто наследовать от класса:
который в execute вместо самоисполнения будет искать и запускать такой Handler, передавая ему себя.
Код: Выделить всё
class RequestJob extends Job
{
public string $url;
public function __construct(string $url)
{
$this->url = $url;
}
}
Код: Выделить всё
abstract class Job implements \yii\queue\Job
{
public function execute($queue): void
{
$handler = \Yii::createObject(static::class . 'Handler');
$handler($this);
}
}
Re: DI и библиотеки
Для контейнера желательно делать библиотеки без изменяемого при работе состояния.wolfandman писал(а): ↑2020.09.24, 16:40 Один инстанс библиотеки Curl создаётся для одного запроса (он имеет состояния).
Например, свой Curl с состоянием можно обернуть в компонент HttpClient без состояния:
Код: Выделить всё
class RequestJobHandler
{
private HttpClient $client;
public function __construct(HttpClient $client) {
$this->client = $client;
}
public function __invoke(RequestJob $job): void {
$response = $this->client->request($job->url);
}
}
Но если всё-таки хочется использовать Curl с состоянием, то тогда для контейнера можно сделать фабрику без состояния и каждый инстанс делать уже через неё:
Код: Выделить всё
class RequestJobHandler
{
private CurlFactory $factory;
public function __construct(CurlFactory $factory) {
$this->factory = $factory;
}
public function __invoke(RequestJob $job): void {
$curl = $this->factory->create(...);
$curl->get($job->url);
}
}
-
- Сообщения: 40
- Зарегистрирован: 2012.06.04, 19:52
Re: DI и библиотеки
Дмитрий, огромное спасибо за ваше время и разъяснения с такими богатыми замечательными примерами!
Идея с ручным использованием контейнера приходила, но сначала переживал, что так делать наверно нехорошо.
Также про фабрику - супер!
Вопрос с решён с вашей помощью.
Спасибо!!
Идея с ручным использованием контейнера приходила, но сначала переживал, что так делать наверно нехорошо.
Также про фабрику - супер!
Вопрос с решён с вашей помощью.
Спасибо!!