Целевой интерфейс фреймворк Laravel 4 не материализуемый


Это связано с этим вопросом Как зарегистрировать пространство имен в laravel 4 но я считаю, что я получил это разработано и пространства имен работают сейчас.

Возникает новая проблема, с которой я столкнулся. Я считаю, что ошибка возникает при попытке ввести подсказку в конструкторе контроллера и связана с использованием пространств имен и использованием ioc.

BindingResolutionException: Target [AppModelsInterfacesPostRepositoryInterface] is not instantiable.
Метод, приведенный ниже, работал отлично, пока я не попытался ввести пространства имен. Я могу удалить все пространства имен и поместить интерфейс и репозитории в том же каталоге, но хотелось бы знать, как заставить пространства имен работать с этим методом использования ioc.

Вот соответствующие файлы.

Маршруты.РНР

Route::resource('posts', 'PostsController');

Примера.php

<?php
use AppModelsInterfacesPostRepositoryInterface;
class PostsController extends BaseController {

    public function __construct( PostRepositoryInterface $posts )
    {
        $this->posts = $posts; 
    }

}

PostRepositoryInterface.php

<?php namespace AppModelsInterfaces;
interface PostRepositoryInterface {
    public function all();
    public function find($id);
    public function store($data);
}

Красноречивый Пострепозитарий.php

<?php namespace AppModelsRepositories;
use AppModelsInterfacesPostRepositoryInterface;
class EloquentPostRepository implements PostRepositoryInterface {

    public function all()
    {
        return Post::all();
            //after above edit it works to this point
            //error: AppModelsRepositoriesPost not found
            //because Post is not in this namespace
    }

    public function find($id)
    {
        return Post::find($id);
    }

    public function store($data)
    {
        return Post::save($data);
    }
}

И вы можете видеть, что композитор dump-autoload сделал свою работу.

Composer / autoload_classmap.php

return array(
    'App\Models\Interfaces\PostRepositoryInterface' => $baseDir . '/app/models/interfaces/PostRepositoryInterface.php',
    'App\Models\Repositories\EloquentPostRepository' => $baseDir . '/app/models/repositories/EloquentPostRepository.php',

    ....
    )

Любые идеи, где или что мне нужно изменить, чтобы сделать так, чтобы это работало с именами, как без них?

Спасибо

2 6

2 ответа:

Я знаю, что на этот вопрос уже дан ответ, но я хотел бы напомнить будущим читателям, что еще одна распространенная причина этой ошибки" target interface is not instantiable " - это то, что вы забыли зарегистрировать поставщика услуг в app/config/app.php.

Это применимо только при расширении класса ServiceProvider, но не при использовании App::bind().

Я слишком часто совершал эту ошибку, чтобы не опубликовать что-то об этом. Поэтому, прежде чем вы пойдете по длинному пути, описанному выше, убедитесь, что зарегистрировали этих поставщиков!

ОК, короткий ответ: используйте полное пространство имен в App:: bind (), чтобы исправить первую ошибку. Затем в красноречивом Пострепозиции.php, поскольку он имеет объявленное пространство имен, пытается обрабатывать любые другие вызовы внешних классов, как если бы они находились в том же пространстве имен. Добавление простого использования поста;' предоставляет PHP знаю, что пост не в том же пространстве имен (модели приложение\репозитории\). Я предполагаю, что это происходит потому, что как только пространство имен используется, другие классы по умолчанию имеют пространство имен независимо от имени класса. Я думал было бы проще всего просто повторно опубликовать весь исправленный и работающий код.

Маршруты.php

<?php

App::bind('App\Models\Interfaces\PostRepositoryInterface',  'App\Models\Repositories\EloquentPostRepository');

Route::resource('posts', 'PostsController');

Постконтроллер.php

<?php
use App\Models\Interfaces\PostRepositoryInterface;

class PostsController extends BaseController {

    public function __construct(PostRepositoryInterface $posts)
    {
        $this->posts = $posts;
    }

Красноречивые Пострепозиции.php

<?php namespace App\Models\Repositories;
use App\Models\Interfaces\PostRepositoryInterface;
use Post;
class EloquentPostRepository implements PostRepositoryInterface {

    public function all()
    {
        return Post::all();
    }

    public function find($id)
    {
        return Post::find($id);
    }

    public function store($data)
    {
        return Post::save($data);
    }
}

Postrepository Interface.php

<?php namespace App\Models\Interfaces;
interface PostRepositoryInterface {
    public function all();
    public function find($id);
    public function store($data);
}

Почта.php здесь нет ничего важного, кроме того, что он не имеет объявленного пространства имен

<?php
class Post extends BaseModel {

    public static $rules = [
        'title' => 'required',
        'body' => 'required',
        'author_id' => 'required|numeric'
    ];

    public static $factory = [
        'title' => 'string',
        'body' => 'text'
    ];

    public function user()
    {
        return $this->belongsTo('User', 'author_id');
    }

}