Целевой интерфейс фреймворк 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 ответа:
Я знаю, что на этот вопрос уже дан ответ, но я хотел бы напомнить будущим читателям, что еще одна распространенная причина этой ошибки"
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'); } }