Home > Software design >  Why's my interface not instantiable even though I have what appears to be the correct files/imp
Why's my interface not instantiable even though I have what appears to be the correct files/imp

Time:11-22

I'm not sure why I'm getting this error that says Illuminate\Contracts\Container\BindingResolutionException: Target [App\Dal\Interfaces\IUploadsRepository] is not instantiable while building [App\Http\Controllers\FileUploadController]. in file /var/www/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 1093 despite having (to my knowledge) everything set up correctly. The spelling and everything else is correct but I'm still not sure what the issue is.

I've tried everything under the sun to make this work but I'm not sure what I'm doing wrong.

What am I missing?

Note: I need to declare the UploadsRepository.php class as abstract because if I don't, then I get a red squiggly line underneath the class name with a warning that says:

Class must be declared abstract or implement methods 'resetScope', 'hidden', 'syncWithoutDetaching', 'update', 'paginate', 'delete', 'findWhereBetween', 'whereHas', 'withCount', 'find', 'getFieldsSearchable', 'create', 'findWhereNotIn', 'setPresenter', 'skipPresenter', 'all', '__callStatic', 'findWhere', 'visible', 'simplePaginate', 'firstOrNew', 'orderBy', 'sync', 'scopeQuery', 'findWhereIn', 'findByField', 'with', 'lists', 'firstOrCreate', 'updateOrCreate', '__call', 'pluck' 

I'm not sure if this is the root of the issue but just want to provide as much info as I possibly can.

Here's FileUploadController.php:

<?php

namespace App\Http\Controllers;

use App\Dal\Interfaces\IUploadsRepository;
Use App\Dal\Repositories\UploadsRepository;

class FileUploadController extends Controller
{

    protected $__uploadsRepository;


    public function __construct(IUploadsRepository $uploadsRepository)
    {
        $this->__uploadsRepository = $uploadsRepository;
    }

    public function getUploads(): string
    {
        return $this->__uploadsRepository->getUploads();
    }
}

Here's IUploadsRepository.php (interface):

<?php

namespace App\Dal\Interfaces;
use Prettus\Repository\Contracts\RepositoryInterface;

interface IUploadsRepository extends RepositoryInterface
{
    public function getUploads();
}

Here's UploadsRepository.php:

<?php

namespace App\Dal\Repositories;

use App\Dal\Interfaces\IUploadsRepository;

abstract class UploadsRepository implements IUploadsRepository
{
    /**
     * @return string
     */
    public function getUploads(): string
    {
        return "test";
    }
}

Here's RepositoryServiceProvider.php:

<?php

namespace App\Providers;

use App\Dal\Interfaces\IUploadsRepository;
use App\Dal\Repositories\UploadsRepository;
use Illuminate\Support\ServiceProvider;

class RepositoryServiceProvider extends ServiceProvider
{
    public function register() {
        $this->app->bind(IUploadsRepository::class,UploadsRepository::class);
    }
}

Here's config/app.php:

'providers' => [
    Prettus\Repository\Providers\RepositoryServiceProvider::class,
    \App\Providers\RepositoryServiceProvider::class,
]

CodePudding user response:

The RepositoryInterface you are extending defines all those methods you see in the error: "'resetScope', 'hidden', 'syncWithoutDetaching', 'update'...". Your concrete implementation UploadsRepository is only implementing getUploads(). To fulfill the contract defined by the RepositoryInterface your concrete implementation needs to implement also the other methods. My recommendation would be to rather than implementing that interface, have your UploadsRepository extends from the Prettus\Repository\Eloquent\BaseRepository class which offers a default implementation for those methods. You can declare like this.

First IUploadsRepository does not need to extend RepositoryInterface, so the declaration would be:

<?php

namespace App\Dal\Interfaces;

interface IUploadsRepository
{
    public function getUploads();
}

And the concrete implementation then goes like this:

<?php

namespace App\Dal\Repositories;

use App\Dal\Interfaces\IUploadsRepository;
use Prettus\Repository\Eloquent\BaseRepository

class UploadsRepository extends BaseRepository implements IUploadsRepository
{
    /**
     * @return string
     */
    public function getUploads(): string
    {
        return "test";
    }
}

You now have a default implementation for the missing methods and can use IUploadsRepository interface to handle the dependency injection via the RepositoryServiceProvider.

  • Related