Reputation: 159
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
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
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