70

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

我在 Laravel 5 中遇到了异常

BindingResolutionException in Container.php line 785:
Target [App\Contracts\CustomModelInterface] is not instantiable.

我所做的没有成功:

  • 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

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(在控制器和存储库之间保留业务逻辑/层)

<?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();
    }
}

作曲家.json

"autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/",
            "App\\Models\\": "app/Models/",
            "App\\Contracts\\": "app/Contracts/",
            "App\\Repositories\\": "app/Repositories/"
        }
    },
4

12 回答 12

52

谢谢大家,但问题出在我的 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(意外转义)。

于 2015-04-17T05:19:51.423 回答
50

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

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

许多小时无用的调试使我得到了这个简短的清单。

于 2016-07-28T14:12:35.607 回答
16

对我来说,我忘记app->providers->RepositoryServiceProvider 在注册方法中像这样在存储库中绑定

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

确保您的RepositoryServiceProvider 已在AppServiceProvider.

public function register()
{   
    $this->app->register(RepositoryServiceProvider::class);
}
于 2017-08-30T17:50:21.980 回答
11

我通过了这个错误运行:

php artisan config:clear
php artisan clear-compiled
php artisan optimize
php artisan config:cache

相关:

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

于 2018-02-12T21:43:14.870 回答
5

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

public function register()
{
    $this->app->singleton(UserRepository::class, EloquentUser::class);
 }

不要忘记名称空间

use Test\Repositories\EloquentUser;
use Test\Repositories\UserRepository;

它对我有用

于 2020-01-09T13:56:56.970 回答
3

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;
}

然后您也可以访问接口方法。

于 2015-04-17T04:09:22.100 回答
2

我刚刚遇到了类似的问题,我的错误原因是我在服务提供者类中设置$defertrue,但我没有实现所需的provides()方法。

如果您已将类的创建推迟到需要它而不是急切地加载,那么您还需要实现该provides方法,该方法应仅返回提供者提供的类的数组。在接口的情况下,我认为它应该是接口的名称而不是具体的类。

例如

public method provides(): array
{
    return [
        MyInterface::class,
    ];
}

当前文档:https ://laravel.com/docs/5.5/providers#deferred-providers

我希望这对其他人有帮助。

于 2018-08-29T14:19:18.173 回答
1

请注意,这也可能是由于类上的 _constructor 被声明为私有,或者被阻止...如果它无法调用构造函数,则绑定将失败

于 2017-03-30T23:08:46.620 回答
1

别担心,伙计们。我有一个解决你的问题的方法。

我有一个例子给你。

Step1: php artisan make:repository Repository/Post //添加这个命令可以创建repository和eloquent文件

Step2:添加该文件后,您必须在要使用的控制器中添加/使用此存储库。

例如:使用 App\Repositories\Contracts\PostRepository;

步骤 3:在控制器中添加该 repo 后,如果您将运行该应用程序,您将收到类似“接口不可实例化”的错误。它的出现是因为您已经创建了一个 repo 并在控制器中使用,但是 laravel 不知道这个存储库在哪里注册并与哪个 eloquent 绑定。所以它会抛出一个错误。

第 4 步:要解决此错误,您必须在AppServiceProvider中将您的 repo 与您的 eloquent 绑定。例如:

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);
    }
}

Step5:绑定 repo 和 eloquent 后,你可以在你的控制器中使用 repo 的所有方法。享受.....

如果您有任何疑问,请告诉我。

于 2018-09-11T09:03:46.533 回答
1

执行这个命令:

composer dump-autoload

此命令将重新映射您的 laravel 自动加载类以及我之前遇到过同样问题的所有其他供应商,这就是您可以将它与“-o”参数一起使用以进行优化的技巧。

于 2020-04-23T14:48:35.140 回答
0

我认为这里的问题是你没有绑定App\Contracts\CustomModelInterface任何东西,所以 Laravel 尝试创建接口实例。

App\Providers\AppRepositoryProvider.php你只有:

$models = array(
            'Model'
        );

但你也应该在这个数组中CustomModel,所以它应该是这样的:

$models = array(
            'Model',
            'CustomModel',
        );
于 2015-04-17T04:57:03.363 回答
0

您要做的最后一件事是使用您绑定到存储库的接口。

设置它并尝试运行您的 laravel 应用程序以确保您没有错误。

就我而言,我的存储库和界面之间存在不匹配。

interface UserRepositoryInterface{
  public function get($userId); 
}

class UserRepository implements UserRepositoryInterface{
  public function get(int $userId);
}

如您所见,接口 get 方法不包含类型提示,但 UserRepository 类的 get 方法具有类型提示。

如果您立即开始使用您的接口绑定,您将不会收到此错误。

于 2017-04-04T16:16:08.520 回答