I have some artisan commands to perform some CLI logic.
class SyncFooCommand extends AbstractBaseSyncCommand
class SyncBarCommand extends AbstractBaseSyncCommand
class SyncBazCommand extends AbstractBaseSyncCommand
Each artisan command extends abstract class AbstractBaseSyncCommand extends Command implements SyncInterface
.
Thanks to that inside the abstract parent class I can put some shared logic.
I inject Carbon or FileSystem and both work in child classes like a charm.
<?php
namespace App\Console\Commands\Sync;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Contracts\Filesystem\Factory as Filesystem;
use League\Csv\Reader;
abstract class AbstractBaseSyncCommand extends Command implements SyncInterface
{
protected $carbon;
protected $fileSystem;
protected $reader;
public function __construct(
Carbon $carbon,
FileSystem $fileSystem,
Reader $reader
) {
parent::__construct();
$this->carbon = $carbon; // works like a charm
$this->fileSystem = $fileSystem; // works like a charm
$this->reader = $reader; // fails, why?
}
}
In SyncWhateverCommand
I can easily call & use $this->carbon
or $this->fileSystem
but as soon as it hits the $this->reader
I get:
Illuminate\Contracts\Container\BindingResolutionException : Target [League\Csv\Reader] is not instantiable while building [App\Console\Commands\Sync\SyncFooCommand].
at /home/vagrant/code/foo/vendor/laravel/framework/src/Illuminate/Container/Container.php:945
941| } else {
942| $message = "Target [$concrete] is not instantiable.";
943| }
944|
> 945| throw new BindingResolutionException($message);
946| }
947|
948| /**
949| * Throw an exception for an unresolvable primitive.
What's wrong? The installation was easy and didn't require to do any bindings. What am I missing?
To sum up:
$csv = $this->reader->createFromPath($path, 'r'); // fails, but I want to use it this way
$csv = Reader::createFromPath($path, 'r'); // works but I don't want facades because they look ugly
Maybe your app should know how to retrieve it? Like
$this->app->bind('SomeAbstraction', function ($app) {
return new Implementation();
});