Я знаю, что этот вопрос задавали так много раз, но ни один из ответов не помог мне.
Я получаю исключение в Laravel 5
BindingResolutionException in Container.php line 785: Target [App\Contracts\CustomModelInterface] is not instantiable.
То, что я сделал без успеха:
App\Providers\AppRepositoryProvider
в app.php
провайдерах php artisan clear-compiled
Буду признателен за любую помощь.
ОБНОВЛЕНИЕ: Я решил проблему (см. Мой ответ ниже ) Спасибо всем.
Состав:
app - Contracts - CustomModelInterface.php - Models - CustomModel.php - Repositories - CustomModelRepository.php - Providers - AppRepositoryProvider.php - Services - MyService.php
App \ Контракты \ CustomModelInterface.php
<?php namespace App\Contracts; interface CustomModelInterface { public function get(); }
App \ Хранилища \ 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 (Держите бизнес-логику / уровень между контроллером и репозиториями)
<?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"); } } }
Мой контроллер выглядит так:
<?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/" } },
Спасибо всем, но проблема была в моем AppRepositoryProvider. Поскольку это обязательное исключение, то, очевидно, проблема заключалась в привязке 🙂
Правильный файл:
<?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"); } } }
Обратите внимание, что я использую "App\Contracts\\{$model}Interface"
(не экранирующий «{» символ), и он генерирует правильную строку App\Contracts\CustomModelInterface
вместо App\Contracts\{$model}Interface
(с неожиданное ускорение).
каждый раз, когда я создаю новую пару репозитория / контракта, я делаю следующее:
Много часов бесполезной отладки привели меня к этому короткому контрольному списку.
Надеюсь, это поможет кому-то. Ура!
В App\Services\MyService.php
вы передаете этот интерфейс с инъекцией зависимостей, которая пытается создать это –
public function __construct(CustomModelInterface $customModel) { $this->Model= $customModel; }
что неправильно.
Попробуйте реализовать, что в этом классе – class MyService implements CustomModelInterface {
и использует функцию этого интерфейса, например –
$this->get();
Или вы используете его – class CustomModelRepository implements CustomModelInterface {
Так что если вы это сделаете –
public function __construct(CustomModelRepository $customModel) { $this->Model= $customModel; }
то вы также можете получить доступ к методам интерфейса.
Я думаю, проблема в том, что вы не привязываете App\Contracts\CustomModelInterface
ко всему, что Laravel пытается создать экземпляр интерфейса.
В App\Providers\AppRepositoryProvider.php
вас есть только:
$models = array( 'Model' );
но вы также должны иметь в этом массиве CustomModel
, поэтому он должен выглядеть так:
$models = array( 'Model', 'CustomModel', );
Обратите внимание, что это также может быть вызвано _constructor при объявлении класса приватным или в противном случае блокируется … Если он не может вызвать конструктор, привязка не удастся
Последнее, что вы делаете, это использовать интерфейс, который вы привязали к репозиторию.
Установите его и попробуйте запустить приложение laravel, чтобы убедиться, что у вас нет ошибок.
В моем случае у меня было несоответствие между моим репозиторием и интерфейсом.
inteface UserRepositoryInterface{ public function get($userId); } class UserRepository implements UserRepositoryInterface{ public function get(int $userId); }
Как вы видите, метод get интерфейса не включает подсказку типа, но метод getReadository класса UserRepository имеет тип подсказки.
Вы не получите эту ошибку, если сразу начнете использовать привязку интерфейса.
Для меня я забыл связать в app->providers->RepositoryServiceProvider
репозиторий, подобный этому, в методе register
public function register() { $this->app->bind(\App\Play\Contracts\PatientRepository::class,\App\Play\Modules\PatientModule::class); }
убедитесь, что ваш RepositoryServiceProvide
r зарегистрирован в AppServiceProvider
.
public function register() { $this->app->register(RepositoryServiceProvider::class); }
надеюсь, что это помогает кому-то.