robs's avatar
Level 1

Target [Illuminate\Database\Migrations\MigrationRepositoryInterface] is not instantiable.

Hi all,

I wanted to create a console command that just checks the status of the migrations and have some custom output. Therefore I inject the Migrator, same as the Laravel MigrateCommand is doing. But I get an error with that dependency injection:

 [Illuminate\Container\BindingResolutionException]
Target [Illuminate\Database\Migrations\MigrationRepositoryInterface] is not instantiable.

The command is nothing fancy so far:

<?php namespace My\Console\Commands;

use Illuminate\Database\Console\Migrations\BaseCommand;
use Illuminate\Database\Migrations\Migrator;
use Symfony\Component\Console\Input\InputOption;

class MigrateCheckCommand extends BaseCommand {

  protected $name = 'migrate:check';

  /**
   * Create a new command instance.
   *
   * @return void
   */
  public function __construct(Migrator $migrator) {
    parent::__construct();

    $this->migrator = $migrator;
  }

  ...
}

The exception is thrown before the constructor and when I remove the dependency injection, it's all fine. But want to use $this->migrator->repositoryExists() in my checks.

Any ideas?

Cheers, Rob

0 likes
3 replies
robjbrain's avatar

I know this is a year old now but i've having the exact same problem, did you manage to resolve this?

@robs

valteroliveira's avatar

You can solve it by using the app() helper.

    /**
     * Create a new command instance.
     *
     */
    public function __construct()
    {
        $migrator = app("migrator");

        parent::__construct($migrator);

    }

3 likes
patrickcarlohickman's avatar

Since I ran into this, I tracked down the solution. I answered this question on StackOverflow here.

The gist is that the Migrator class is not registered in the IoC container, so when Laravel resolves your command, it attempts to build a new one from scratch and fails. There is a migrator instance bound to the migrator alias, however.

Laravel's migrate command works because the command is registered in the IoC container by Illuminate\Foundation\Providers\ArtisanServiceProvider, and this is where the migrator dependency is injected. Following this logic, you should register your own command in your AppServiceProvider (or other service provider you setup) to inject the migrator:

$this->app->singleton(\My\Console\Commands\MigrateCheckCommand::class, function ($app) {
    return new \My\Console\Commands\MigrateCheckCommand($app['migrator']);
});

I didn't test this, but I believe you could also just register the Migrator class name in the IoC container, and then Laravel should be able to resolve the dependency without having to manually register the command:

$this->app->singleton(\Illuminate\Database\Migrations\Migrator::class, function ($app) {
    return $app['migrator'];
});
2 likes

Please or to participate in this conversation.