Laravel 5 - 接口不可实例化

And*_*kov 47 php repository-pattern laravel laravel-5 laravel-ioc

我知道这个问题被问了很多次,但没有一个答案对我有帮助.

我在Laravel 5中遇到了异常

BindingResolutionException in Container.php line 785:
Target [App\Contracts\CustomModelInterface] is not instantiable.
Run Code Online (Sandbox Code Playgroud)

我没做过什么就做了:

  • 注册App\Providers\AppRepositoryProviderapp.php供应商
  • php artisan clear-compiled
  • 如果我替换MyService中的存储库上的接口,一切都有效,但我觉得这是错误的(它应该由IoC容器处理吗?).

结构体:

app
  - Contracts
    - CustomModelInterface.php
  - Models
    - CustomModel.php
  - Repositories
    - CustomModelRepository.php
  - Providers
    - AppRepositoryProvider.php
  - Services
    - MyService.php
Run Code Online (Sandbox Code Playgroud)

应用程序\合同\ CustomModelInterface.php

<?php namespace App\Contracts;

interface CustomModelInterface {
    public function get();
}
Run Code Online (Sandbox Code Playgroud)

应用程序\库\ 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';
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

软件\供应商\ 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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的控制器看起来像:

<?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();
    }
}
Run Code Online (Sandbox Code Playgroud)

composer.json

"autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/",
            "App\\Models\\": "app/Models/",
            "App\\Contracts\\": "app/Contracts/",
            "App\\Repositories\\": "app/Repositories/"
        }
    },
Run Code Online (Sandbox Code Playgroud)

And*_*kov 40

谢谢大家,但问题出现在我的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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意,我正在使用"App\Contracts\\{$model}Interface"(不是转义"{"符号)并且它生成正确的字符串App\Contracts\CustomModelInterface而不是App\Contracts\{$model}Interface(具有意外的转义).


Vla*_*scu 19

每次我创建一个新的存储库/合同对时,我都要确保执行以下操作:

  1. 检查服务提供者中使用的类(复制/粘贴命名空间)
  2. 在config/app.php中注册一个新绑定
  3. php artisan优化

经过几个小时无用的调试,我得到了这份简短的清单.

  • 我忘了#2,救了我 (2认同)

Beu*_*Ana 8

对我来说,我忘了app->providers->RepositoryServiceProvider 在register方法中像这样绑定到存储库中

public function register()
{
    $this->app->bind(
        \App\Play\Contracts\PatientRepository::class,
        \App\Play\Modules\PatientModule::class
    );
}
Run Code Online (Sandbox Code Playgroud)

确保您的RepositoryServiceProvider已在中注册AppServiceProvider

public function register()
{   
    $this->app->register(RepositoryServiceProvider::class);
}
Run Code Online (Sandbox Code Playgroud)


小智 6

通过在 app/providers/AppServiceProvider 中添加存储库可以解决该问题,如下例所示。

public function register()
{
    $this->app->singleton(UserRepository::class, EloquentUser::class);
 }
Run Code Online (Sandbox Code Playgroud)

不要忘记名称空间

use Test\Repositories\EloquentUser;
use Test\Repositories\UserRepository;
Run Code Online (Sandbox Code Playgroud)

这对我有用


Con*_*ech 5

我遇到了运行此错误:

php artisan config:clear
php artisan clear-compiled
php artisan optimize
php artisan config:cache
Run Code Online (Sandbox Code Playgroud)

相关:

目标不可实例化。Laravel 5-应用程序绑定服务提供商