2015-02-15 3 views
0

Я нашел много вопросов о своей проблеме и попробовал (я думаю) все решения, но я не могу заставить их работать. Вероятно, я пропускаю что-то очень легкое.Injection in Repository

Я использую Laravel 5. Я пытаюсь реализовать шаблон репозитория. У меня есть яркая модель '\ Notos \ Kind'.

Тогда у меня есть этот интерфейс:

namespace Notos\Contracts; 

interface Kind 
{ 
    public function findByName($name); 
} 

Мой Repository выглядит следующим образом:

namespace Notos\Repository; 


use Illuminate\Database\Eloquent\Model; 
use Notos\Contracts\Kind as KindContract; 

class Kind implements KindContract 
{ 
    protected $kind; 

    public function __construct(Model $kind) 
    { 
     $this->kind = $kind; 
    } 

    public function findByName($name) 
    { 
     return $this->kind->firstOrCreate(array('name' => $name)); 
    } 
} 

Мой ServiceProvider:

namespace Notos\Providers; 

use Illuminate\Support\ServiceProvider; 
use Notos\Kind; 
use Notos\Repository\Kind as KindRepository; 


class RepoServiceProvider extends ServiceProvider 
{ 

    /** 
    * Register the service provider. 
    * 
    * @return void 
    */ 
    public function register() 
    { 
     $this->app->bind('Notos\Contracts\Kind', function ($app) { 
      return new KindRepository(new Kind); 
     }); 
    } 
} 

И мой контроллер, который использует репозиторий:

namespace Notos\Http\Controllers; 

use Notos\Repository\Kind as KindRepository; 

class KindController extends Controller 
{ 
    protected $kind; 

    public function __construct(KindRepository $kind) 
    { 
     $this->kind = $kind; 
    } 

    public function find($name) 
    { 
     return $this->kind->findByName($name); 
    } 
} 

Этот провайдер зарегистрирован в конфигурации/app.php

Когда я пытаюсь выполнить KindController @ найти я получаю эту ошибку:

BindingResolutionException in Container.php line 785: 
Target [Illuminate\Database\Eloquent\Model] is not instantiable. 

Я не могу найти то, что я делаю неправильно , Он отлично работает, если я изменю __construct (Model $ kind) на __construct (Kind $ kind).

Любые идеи?

ответ

1

Первое, что я бы посоветовал добавить к вашим именам классов функцию, например, вместо Kind для хранилища KindRepository, то же самое для контракта. В противном случае у вас будет 3 класса классов (конечно, в разных пространствах имен), но будет сложно проанализировать код.

Проблема заключается в том, что в вашем KindController вы пытаетесь ввести KindRepository напрямую, но в конструкторе вы используете Model. Это не сработает, потому что Model - это только абстрактный класс. Что вы должны сделать, чтобы заставить его работать?

В коде:

$this->app->bind('Notos\Contracts\Kind', function ($app) { 
      return new KindRepository(new Kind); 
     }); 

вы сказали Laravel, что, когда вы будете использовать Notos\Contracts\Kind он должен создать KindRepository для вас с Kind в конструкторе - посмотреть, что вы сказали здесь о договоре, а не о самом хранилище.

Чтобы заставить его работать, вы должны использовать в своем контроллере не свой репозиторий, а ваш контракт.

Вместо линии:

use Notos\Repository\Kind as KindRepository; 

вы должны написать:

use Notos\Contracts\Kind as KindRepository; 

и он должен работать.

+0

конечно ... очевидно! – BakGat