Abhishek
Abhishek

Reputation: 159

How to make repository request in Laravel?

I am using Repository pattern in laravel to fetch records from a table but getting error like

"Target [App\Repositories\ThirdPartyRepository] is not instantiable while building [App\Http\Controllers\Dashboardcontroller]."

This is the following structure I have

app ->
  Repositories
     ->Thirdpartyrepository.php
     -> Thirdpartyrepositoryinterface.php
     -> ThirdpartyServiceProvider.php

Thirdpartyrepositoryinterface.php

    namespace App\Repositories;
    
    interface ThirdpartyRepositoryInterface
    {
        
        public function getAll();
        
    }

Thirdpartyrepository.php

    namespace App\Repositories;
    
    abstract class ThirdPartyRepository implements ThirdpartyRepositoryInterface
    {
        
        public function getAll(){
            $getcmp= DB::table('xyz')
                ->orderBy('id', 'desc')
                ->select('name', 'id', 'created_at')
                ->get();
            return $getcmp;
        }
        
    }

ThirdpartyServiceProvider.php

    namespace App\Repositories;
    use Illuminate\Support\ServiceProvider;
    class ThirdpartyServiceProvider extends ServiceProvider
    {
        
        public function register(){
            $this->app->bind(
                'App\Repositories\ThirdpartyRepositoryInterface',
                'App\Repositories\ThirdPartyRepository'
            );
        }
    }

Dashboardcontroller.php

    use App\Repositories\ThirdPartyRepository;
        protected $thirdparty;
        public function __construct(ThirdPartyRepository $thirdparty){
                $this->thirdparty= $thirdparty;
            }
    
        public function getproducts(){
                $getCompanies=$this->thirdparty->getAll();
                dd ($getCompanies);
        }

Upvotes: 2

Views: 1425

Answers (2)

user3532758
user3532758

Reputation: 2271

To explain my comment in detail, in your Dashboard controller, you are injecting the implementation instead of the interface. Your current code:

public function __construct(ThirdPartyRepository $thirdparty){
  $this->thirdparty= $thirdparty;
}

Main advantage to using interfaces is that it allows you to abstract your code. Since you are injecting the implementation, this advantage is lost. Say for instance, when you code a new implementation you would need to change this controller. Classes should be closed for modification as much as possible (SOLID principle).

You would need to change that method to:

public function __construct(Thirdpartyrepositoryinterface $thirdparty){ //inject interface
  $this->thirdparty= $thirdparty;
}

And my third comment: Instead of abstract class, you should have a normal class implementing the interface.

class ThirdPartyRepository implements ThirdpartyRepositoryInterface //remove abstract
{ 
    public function getAll(){

And you need to add your service provider to the providers array in config.php.

'providers' => [
    ...
    App\Providers\ThirdpartyServiceProvider::class, //your new service provider.

],

Upvotes: 1

aimme
aimme

Reputation: 6808

The problem is that you are trying to bind an abstract class to interface. Change

abstract class ThirdPartyRepository

to

class ThirdPartyRepository

and also you should inject the interface not the concrete class like this

public function __construct(ThirdpartyRepositoryInterface $thirdparty){
    $this->thirdparty= $thirdparty;
}

Otherwise your whole purpose of using contracts for binding is meaningless. Bind interface to implementation.

Upvotes: 0

Related Questions