gRoberts's avatar

Binding Interfaces To Implementations - Interface is not instantiable

Hey all,

Attempting to use the IoC functionality within Lumen/Laravel for an API I am building where we can easily swap out an authenticator based on it's interface.

As you can see below, in my main AppServiceProvider, I am binding my interface to an implementation of that interface and attempting to use it within my AuthProvider.

I've tried injecting the interface on a controller too with no luck what so ever.

Any suggestions on what I could be doing wrong?

Target [App\Contracts\AuthenticationContract] is not instantiable while building [App\Http\Controllers\AuthController].

Target [App\Contracts\AuthenticationContract] is not instantiable while building [App\Providers\AuthProvider].

<?php namespace App\Providers;

use App\Services\TokenAuthentication;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->register(\App\Providers\AuthServiceProvider::class);
        $this->app->register(\App\Providers\EventServiceProvider::class);
        $this->app->bind(AuthenticationContract::class, TokenAuthentication::class);

        app(\Dingo\Api\Auth\Auth::class)->extend('custom', function ($app) {
            return app(\App\Providers\AuthProvider::class);
        });
    }
}

<?php namespace App\Providers;

use Dingo\Api\Contract\Auth\Provider;
use Dingo\Api\Routing\Route;
use Illuminate\Http\Request;
use Dingo\Api\Auth\Provider\Authorization;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;

class AuthProvider extends Authorization implements Provider
{
    private $auth;

    public function __construct(\App\Contracts\AuthenticationContract $auth)
    {
        $this->auth = $auth;
    }

    public function authenticate(Request $request, Route $route)
    {
        throw new UnauthorizedHttpException('Unable to authenticate with supplied username and password.');
    }

    public function getAuthorizationMethod()
    {
        return 'bearer';
    }
}
<?php

namespace App\Services;

use App\Contracts\AuthenticationContract;

class TokenAuthentication implements AuthenticationContract
{
    public function authenticate($credentials)
    {

    }

    public function validateToken($token)
    {

    }

    public function validateClient($client_id, $secret)
    {

    }
}
0 likes
2 replies
bwrice's avatar
bwrice
Best Answer
Level 11

Try adding

App::bind('App\Contracts\AuthenticationContract','App\Services\TokenAuthentication');

to your routes.

If that fixes the problem you can create your own service provider and move the binding there and then you'll have to register it in your configuration (/config/app.php)

There's a video on Laracasts about it (You can probably start around 9:30):

https://laracasts.com/lessons/repositories-simplified

1 like
gRoberts's avatar

That worked, however failed when attempting to inject before the routes were being included.

After adding it into the config/app.php, all worked straight away.

Thanks :)

Please or to participate in this conversation.