如何向Laravel作业注入依赖项

37

我正在将Laravel作业添加到我的队列中,代码如下:

$this->dispatchFromArray(
    'ExportCustomersSearchJob',
    [
        'userId' => $id,
        'clientId' => $clientId
    ]
);

当实现ExportCustomersSearchJob类时,我希望将userRepository作为依赖注入。请问如何实现?

我尝试了以下方法,但未成功。

class ExportCustomersSearchJob extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels, DispatchesJobs;

    private $userId;

    private $clientId;

    private $userRepository;


    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($userId, $clientId, $userRepository)
    {
        $this->userId = $userId;
        $this->clientId = $clientId;
        $this->userRepository = $userRepository;
    }
}
3个回答

78

您在handle方法中注入您的依赖项:

class ExportCustomersSearchJob extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels, DispatchesJobs;

    private $userId;

    private $clientId;

    public function __construct($userId, $clientId)
    {
        $this->userId = $userId;
        $this->clientId = $clientId;
    }

    public function handle(UserRepository $repository)
    {
        // use $repository here...
    }
}

如果我有一个父作业类,其中包含一个handle方法和子作业类,这些子作业类具有从父类的handle方法调用的run方法,我想在子作业类的run方法中能够使用类型提示来引用存储库,但是这样会导致父类中出现“参数过少”的错误。 - Robert
只需使用继承。在最外层的子作业中对所需的所有类进行类型提示,然后将对象传递给父类。例如,您的子作业可能具有以下内容handle(UserRepository $repository, FooService $fooService)并通过向父级传递FooService来开始:parent::__handle($fooService) - Jason

3

如果有人想知道如何将依赖注入到handle函数中:

请在服务提供者中添加以下内容。

$this->app->bindMethod(ExportCustomersSearchJob::class.'@handle', function ($job, $app) {
    return $job->handle($app->make(UserRepository::class));
});
Laravel任务处理文档,这里有关于任务的详细说明。

2
当您使用dispatch()函数时,Laravel会自动为您执行此操作。无需手动绑定依赖项。 - Jason
这是 Laravel 5 之后的新功能吗? - m_____ilk
自5.0版本以来,它一直是这样运作的。文档显示通过服务容器进行注入: https://laravel.com/docs/5.0/queues#basic-usage 只要类或服务在服务容器中注册,Laravel就会自动将其注入到handle()方法中。HTTP控制器方法也是同样的道理。 - Jason

1

Laravel v5及以上版本。

自Laravel v5起,作业中的依赖关系由它们自己处理。 文档中写道:

“您可以在handle方法上类型提示任何需要的依赖项,服务容器将自动注入它们”

因此,现在您只需在Job的handle方法中添加要使用的依赖项即可。例如:

use From/where/ever/UserRepository;

class test implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct()
    {
//
    }

    public function handle(UserRepository $userRepository)
    {
//        $userRepository can be used now.
    }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接