Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5 IoC container unable to resolve contextual bindings when using method injection

Inside my Laravel 5 application, I have registered a contextual binding for an interface in a service provider like so:

$this->app->when('App\Http\Controllers\MyController')
    ->needs('App\Contracts\MyRepositoryInterface')
    ->give('App\Repositories\MyRepostory');

Inside the controller MyController, I have the index() method into which I am trying to inject MyRepositoryInterface like so:

public function index(App\Contracts\MyRepositoryInterface $repo)
{
    // Stuff
}

The problem is, the above doesn't work and gives this error:

BindingResolutionException in Container.php line 754:

Target [App\Contracts\MyRepositoryInterface] is not instantiable.

However, if I change the contextual binding into a normal binding like the following, it works:

$this->app->bind(
    'App\Contracts\MyRepositoryInterface',
    'App\Repositories\MyRepository'
);

Another thing that I have noticed is that the same contextual binding works fine for the constructor method for the controller like so:

public function __constructor(App\Contracts\MyRepositoryInterface $repo)
{
    // Stuff
}

This makes me wonder, is contextual binding not supported for method (except constructors) injection? Or is this still a work in progress and will be supported once Laravel 5 comes out?

Or am I doing something terribly wrong?

Any advice would be greatly appreciated, as I have been pulling my hair over this!

like image 203
robinmitra Avatar asked Nov 09 '22 22:11

robinmitra


1 Answers

Laravel 5 does not support this as it was not intended to work on methods. A workaround is by extending the ValidatesWhenResolved interface with your own, like:

namespace Authentication\Requests\Contracts;
use Illuminate\Contracts\Validation\ValidatesWhenResolved;

interface Validatable extends ValidatesWhenResolved {}

And than you can bind to that interface:

$this->app->bind('Authentication\Requests\Contracts\Validatable',
'Authentication\Requests\Login');

It is not DRY though.

like image 193
Stefan Avatar answered Nov 15 '22 12:11

Stefan