Я знаю, что этот вопрос задавался много раз, но ни один из ответов не помог мне.
Я получаю исключение в 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->providers->RepositoryServiceProvider
хранилище, как это в методе регистра
public function register()
{
$this->app->bind(
\App\Play\Contracts\PatientRepository::class,
\App\Play\Modules\PatientModule::class
);
}
Убедитесь, что ваш RepositoryServiceProvide
г зарегистрирован в AppServiceProvider
,
public function register()
{
$this->app->register(RepositoryServiceProvider::class);
}
На 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;
}
тогда также вы можете получить доступ к методам интерфейса.
Я прошел эту ошибку:
php artisan config:clear
php artisan clear-compiled
php artisan optimize
php artisan config:cache
Относится к:
Цель не является инстанцируемой. Laravel 5 — поставщик услуг привязки приложений
Я только что столкнулся с проблемой, похожей на эту, и причиной моей ошибки было то, что я установил $defer
в true
в классе поставщика услуг, но я не реализовал требуемый provides()
метод.
Если вы отложили создание своего класса до тех пор, пока он не будет необходим, а не загружен с нетерпением, то вам также необходимо реализовать provides
метод, который должен просто возвращать массив классов, которые предоставляет провайдер. Я полагаю, что в случае интерфейса это должно быть имя интерфейса, а не конкретный класс.
Например.
public method provides(): array
{
return [
MyInterface::class,
];
}
Текущая документация: https://laravel.com/docs/5.5/providers#deferred-providers
Я надеюсь, что это помогает кому-то еще.
Не волнуйтесь, ребята. У меня есть решение вашей проблемы.
У меня есть пример для вас.
Шаг 1: php artisan make: репозиторий Репозиторий / Пост // Добавив эту команду, вы можете создать репозиторий и красноречивые файлы
Шаг 2: После добавления этого файла вы должны добавить / использовать этот репозиторий в контроллере, в котором вы хотите использовать.
например: использовать App \ Repositories \ Contracts \ PostRepository;
Шаг 3: После добавления этого репозитория в ваш контроллер, если вы запустите приложение, вы получите сообщение об ошибке «Интерфейс не создается». Это происходит потому, что вы создали репо и используете его в контроллере, но laravel не знает, где этот репозиторий зарегистрирован и с каким красноречивым связыванием. Так что это выдает ошибку.
Шаг 4: Чтобы устранить эту ошибку, вы должны связать репозиторий с вашим красноречивым в AppServiceProvider.
Например:
Файл 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);
}
}
Шаг 5: После привязки репо и красноречивых вы можете использовать все методы репо в вашем контроллере. Наслаждаться…..
Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы.
Я думаю, что проблема в том, что вы не связываете App\Contracts\CustomModelInterface
ни к чему, так что Laravel пытается создать экземпляр интерфейса.
В App\Providers\AppRepositoryProvider.php
у вас есть только:
$models = array(
'Model'
);
но вы должны иметь в этом массиве CustomModel
также, так это должно выглядеть так:
$models = array(
'Model',
'CustomModel',
);