Solution 1:

Thank you everyone, but problem was in my AppRepositoryProvider. As it's binding exception, then obviously the problem was with binding :)

Correct file is:

<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppRepositoryProvider extends ServiceProvider {

    public function boot() {}

    public function register() {
        $models = array(
            'CustomModel',
            'CustomModel2',
            'CustomModel3'
        );

        foreach ($models as $model) {
            $this->app->bind("App\Contracts\\{$model}Interface", "App\Repositories\\{$model}Repository");
        }
    }
}

Note, that I'm using "App\Contracts\\{$model}Interface" (not escaping "{" symbol) and it generate correct string App\Contracts\CustomModelInterface instead of App\Contracts\{$model}Interface (with unexpected escaping).

Solution 2:

Every time I create a new repository/contract pair I make sure I do the following:

  1. check the classes used in the service provider (copy/paste the namespaces)
  2. register a new binding in config/app.php
  3. php artisan optimize

Many hours of useless debugging led me to this short checklist.

Solution 3:

For me, I forgot to bind in app->providers->RepositoryServiceProvider the repository like this in the register method

public function register()
{
    $this->app->bind(
        \App\Play\Contracts\PatientRepository::class,
        \App\Play\Modules\PatientModule::class
    );
}

Make sure your RepositoryServiceProvider is registered in AppServiceProvider.

public function register()
{   
    $this->app->register(RepositoryServiceProvider::class);
}

Solution 4:

I got past this error running:

php artisan config:clear
php artisan clear-compiled
php artisan optimize
php artisan config:cache

Related to:

Target is not instantiable. Laravel 5 - App binding service provider