Je sais que cette question a été posée à maintes reprises, mais aucune des réponses ne m'a aidé.
Je reçois une exception dans Laravel 5
BindingResolutionException in Container.php line 785:
Target [App\Contracts\CustomModelInterface] is not instantiable.
Ce que j'ai fait sans succès:
App\Providers\AppRepositoryProvider
dans les fournisseurs app.php
php artisan clear-compiled
Structure:
app
- Contracts
- CustomModelInterface.php
- Models
- CustomModel.php
- Repositories
- CustomModelRepository.php
- Providers
- AppRepositoryProvider.php
- Services
- MyService.php
App\Contracts\CustomModelInterface.php
<?php namespace App\Contracts;
interface CustomModelInterface {
public function get();
}
App\Repositories\CustomModelRepository.php
<?php namespace App\Repositories;
use App\Contracts\CustomModelInterface;
use App\Models\CustomModel;
class CustomModelRepository implements CustomModelInterface {
private $Model;
public function __construct(CustomModel $model) {
$this->Model = $model;
}
public function get() {
return 'result';
}
}
App\Services\MyService.php (Conservez la logique/couche métier entre le contrôleur et les référentiels)
<?php namespace App\Services;
use App\Contracts\CustomModelInterface;
class MyService {
private $Model;
public function __construct(CustomModelInterface $customModel) {
$this->Model= $customModel;
}
public function getAll() {
return $this->Model->get();
}
}
App\Providers\AppRepositoryProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppRepositoryProvider extends ServiceProvider {
public function boot() {}
public function register() {
$models = array(
'CustomModel'
);
foreach ($models as $idx => $model) {
$this->app->bind("App\Contracts\{$model}Interface", "App\Repositories\{$model}Repository");
}
}
}
Mon contrôleur ressemble à:
<?php namespace App\Http\Controllers;
use App\Services\MyService;
class SuperController extends Controller {
private $My;
public function __construct(MyService $myService) {
$this->My = $myService;
}
public function getDetails() {
return $this->My->getAll();
}
}
composer.json
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"App\\Models\\": "app/Models/",
"App\\Contracts\\": "app/Contracts/",
"App\\Repositories\\": "app/Repositories/"
}
},
Merci à tous, mais le problème était dans mon AppRepositoryProvider. Comme il s'agit d'une exception de liaison, le problème était évidemment lié à la liaison :)
Le fichier correct est:
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppRepositoryProvider extends ServiceProvider {
public function boot() {}
public function register() {
$models = array(
'CustomModel',
'CustomModel2',
'CustomModel3'
);
foreach ($models as $model) {
$this->app->bind("App\Contracts\\{$model}Interface", "App\Repositories\\{$model}Repository");
}
}
}
Notez que j'utilise "App\Contracts\\{$model}Interface"
(sans échapper le symbole "{") et qu'il génère la chaîne correcte App\Contracts\CustomModelInterface
au lieu de App\Contracts\{$model}Interface
(avec l'échappement inattendu).
Chaque fois que je crée un nouveau couple référentiel/contrat, je m'assure de procéder comme suit:
De nombreuses heures de débogage inutile m'ont conduit à cette courte liste de contrôle.
Pour moi, j'ai oublié de lier dans app->providers->RepositoryServiceProvider
Le référentiel comme celui-ci dans la méthode register
public function register()
{
$this->app->bind(
\App\Play\Contracts\PatientRepository::class,
\App\Play\Modules\PatientModule::class
);
}
Assurez-vous que votre RepositoryServiceProvide
r est enregistré dans AppServiceProvider
.
public function register()
{
$this->app->register(RepositoryServiceProvider::class);
}
J'ai dépassé cette erreur en cours d'exécution:
php artisan config:clear
php artisan clear-compiled
php artisan optimize
php artisan config:cache
Relatif à:
La cible n'est pas instanciable. Laravel 5 - Fournisseur de service de liaison des applications
Sur App\Services\MyService.php
, vous passez cette interface avec une injection de dépendance qui tente d’instancier cela -
public function __construct(CustomModelInterface $customModel) {
$this->Model= $customModel;
}
ce qui est faux.
Essayez d'implémenter cela dans cette classe - class MyService implements CustomModelInterface {
et utilisez la fonction de cette interface comme -
$this->get();
Ou vous l'utilisez - class CustomModelRepository implements CustomModelInterface {
Donc si vous le faites -
public function __construct(CustomModelRepository $customModel) {
$this->Model= $customModel;
}
alors aussi vous pouvez accéder aux méthodes d'interface.
Je viens de rencontrer un problème similaire à celui-ci et la cause de mon erreur est que j'avais défini $defer
sur true
dans la classe de fournisseur de service, mais que je n'avais pas mis en œuvre la méthode provides()
requise.
Si vous avez différé la création de votre classe jusqu'à ce que vous en ayez besoin plutôt que de la charger rapidement, vous devez également implémenter la méthode provides
qui devrait simplement renvoyer un tableau des classes fournies par le fournisseur. Dans le cas d'une interface, je pense que ce devrait être le nom de l'interface plutôt que la classe concrète.
Par exemple.
public method provides(): array
{
return [
MyInterface::class,
];
}
Documentation actuelle: https://laravel.com/docs/5.5/providers#deferred-providers
J'espère que cela aide quelqu'un d'autre.
Ne vous inquiétez pas les gars. J'ai une solution à votre problème.
J'ai un exemple pour vous.
Etape 1: php artisan: make: repository Repository/Post // En ajoutant cette commande, vous pouvez créer un repository et des fichiers éloquents
Étape 2: Après avoir ajouté ce fichier, vous devez ajouter/utiliser ce référentiel dans le contrôleur dans lequel vous souhaitez utiliser.
par exemple: utilisez App\Repositories\Contracts\PostRepository;
Étape 3: Après avoir ajouté ce dépôt dans votre contrôleur, si vous exécutez l'application, vous obtiendrez une erreur du type "L'interface n'est pas instable". Cela vient du fait que vous avez créé un référentiel et utilisé dans un contrôleur, mais Laravel ne sait pas où se trouve ce référentiel, auquel il est lié. Pour que cela jette une erreur.
Étape 4: Pour résoudre cette erreur, vous devez lier votre référentiel avec votre éloquent dans AppServiceProvider . Par exemple:
Fichier AppServiceProvider.php
<?php
namespace App\Providers;
// **Make sure that your repo file path and eloquent path must be correct.**
use App\Repositories\Contracts\PostRepository; // **Use your repository here**
use App\Repositories\Eloquent\EloquentPostRepository; **// Use your eloquent here**
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
/**
* Register any application services.
*
* @return void
*/
public function register() {
**// And bind your repository and eloquent here. **
$this->app->bind(PostRepository::class, EloquentPostRepository::class);
}
}
Étape 5: Après avoir lié repo et éloquent, vous pouvez utiliser toutes les méthodes de repo dans votre contrôleur. Prendre plaisir.....
S'il vous plaît laissez-moi savoir si vous avez une requête.
La dernière chose à faire est d'utiliser l'interface que vous avez liée au référentiel.
Configurez-le et essayez d’exécuter votre application laravel pour vous assurer que vous n’obtenez aucune erreur.
Dans mon cas, il y avait une incompatibilité entre mon référentiel et l'interface.
interface UserRepositoryInterface{
public function get($userId);
}
class UserRepository implements UserRepositoryInterface{
public function get(int $userId);
}
Comme vous pouvez le constater, la méthode get de l'interface n'inclut pas d'indicateur de type, mais la méthode get de la classe UserRepository a un indicateur de type.
Vous n'obtiendrez pas cette erreur si vous commencez immédiatement à utiliser votre liaison d'interface.
Je pense que le problème ici est que vous ne liez pas App\Contracts\CustomModelInterface
à quoi que ce soit, alors Laravel essaie de créer une instance d'interface.
Dans App\Providers\AppRepositoryProvider.php
vous avez seulement:
$models = array(
'Model'
);
mais vous devriez aussi avoir dans ce tableau CustomModel
, donc ça devrait ressembler à ça:
$models = array(
'Model',
'CustomModel',
);
Notez que cela peut aussi être causé par le _constructor de la classe déclaré privé ou bloqué d'une autre manière ... S'il ne peut pas appeler le constructeur, la liaison échouera