如何在 Laravel Job Class 中使用绑定实现?

How to use binded implementation in Laravel Job Class?

我会在我的工作中使用接口,并在工作中获得它的上下文实现 classes。

我读了所有的 tuts。

我注册了:

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app
            ->when(SendinBlueJob::class)
            ->needs(MessageProviderInterface::class)
            ->give(SendinBlueService::class);
    }
}

我派工:

class MessageObserver
{
    public function created(MessageInterface $message)
    {
        SendinBlueJob::dispatch($message);
    }
}

在职class我想获得绑定服务:

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

     public $message;
     public $messageProvider;

    public function __construct(MessageInterface $message, MessageProviderInterface $messageProvider)
    {
        $this->message = $message;
        $this->messageProvider = $messageProvider;
        $this->handle();
     }

    public function handle()
    {
        dd($this->messageProvider);
    }
}

我无法分派作业,因为服务器抛出错误:

Too few arguments to function App\Jobs\SendinBlueJob::__construct(), 1 passed in /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Bus/Dispatchable.php on line 16 and exactly 2 expected

我明白了,但我不明白为什么Laravel在构造函数中调用接口时不注入绑定服务。

您可以在 handle 方法中注入依赖项。

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

    public $message;

    public function __construct(MessageInterface $message)
    {
        $this->message = $message;
    }

    public function handle(MessageProviderInterface $messageProvider)
    {
        dd(
            $this->message, // MessageInterface
            $messageProvider // SendInBlueService
        );
    }
}

更新

解决方案 1

因为您正在使用上下文绑定,并且当您通过方法进行依赖注入时上下文绑定不起作用(这是在作业中执行此操作的唯一方法),请考虑以下方法...

在您的服务提供商中:

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->when(MessagesController::class) // Your controller
                  ->needs(MessageProviderInterface::class)
                  ->give(SendinBlueService::class);
    }
}

在你的控制器中:

class MessagesController extends Controller
{
    protected $messageProvider;

    public function __construct(MessageProviderInterface $messageProvider)
    {
        $this->messageProvider = $messageProvider;
    }

    public function store(Request $request)
    {
        // ...

        // Create your message
        $message = Message::create($request->all());

        // Dispatch your job in the controller
        SendInBlueJob::dispatch($message, $this->messageProvider);

        // ...
    }
}

在你的工作中:

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

    protected $message;

    protected $messageProvider;

    public function __construct(MessageInterface $message, MessageProviderInterface $messageProvider)
    {
        $this->message = $message;

        $this->messageProvider = $messageProvider;
    }

    public function handle()
    {
        dd($this->messageProvider);
    }
}

解决方案 2

或者,不要使用上下文绑定。您可以执行类似于以下操作的操作...

新建 SendinBlueMessageProviderInterface:

interface SendinBlueMessageProviderInterface extends MessageProviderInterface
{
    //
}

将接口绑定到您的实现。

$this->app->bind(
    SendinBlueMessageProviderInterface::class,
    SendinBlueService::class
);

现在您将能够通过 handle 方法注入消息提供程序。

public function handle(SendinBlueMessageProviderInterface $messageProvider)
{
    dd($messageProvider);
}