After watching Jeffrey's awesome command-oriented architecture videos, I'm inspired to try implementing synchronous Jobs for my eCommerce project (AddItemToCart, RemoveItemFromCart, etc.). But one thing I'm trying to wrap my head around is dependency injection within jobs.
From the Laravel 5.1 documentation in the Serve Container chapter, it seems that dependencies can be injected into the constructor for the job like this:
namespace App\Jobs;
use App\User;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Contracts\Bus\SelfHandling;
class PurchasePodcast implements SelfHandling
{
/**
* The mailer implementation.
*/
protected $mailer;
/**
* Create a new instance.
*
* @param Mailer $mailer
* @return void
*/
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
/**
* Purchase a podcast.
*
* @return void
*/
public function handle()
{
//
}
}
But if I create a dummy job, add to a controller method, and try to dispatch the job with $this->dispatch(new Foo), I get the following exception:
Argument 1 passed to App\Jobs\Foo::__construct() must be an instance of Illuminate\Contracts\Mail\Mailer, none given, called in {directory} and defined
However, as soon as I use method injection to add that dependency into the handle() method, it works. In fact, when you look at the Queue chapter of the documentation, a similar example is used and the Mailer is injected into the handle() method instead of in the constructor.
<?php
namespace App\Jobs;
use App\User;
use App\Jobs\Job;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendReminderEmail extends Job implements SelfHandling, ShouldQueue
{
use InteractsWithQueue, SerializesModels;
protected $user;
/**
* Create a new job instance.
*
* @param User $user
* @return void
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Execute the job.
*
* @param Mailer $mailer
* @return void
*/
public function handle(Mailer $mailer)
{
$mailer->send('emails.reminder', ['user' => $this->user], function ($m) {
//
});
$this->user->reminders()->create(...);
}
}
Am I missing something, or is the DI example in the Service Container chapter incorrect?