Мое сообщение об ошибке:
Illuminate \ Container \ BindingResolutionException
Target [Project\Backend\Service\Validation\ValidableInterface] is not instantiable.
Я понимаю, что интерфейсы и абстрактные классы не являются экземплярами, поэтому я знаю, что Laravel не должен пытаться создать экземпляр моего интерфейса. Тем не менее, каким-то образом это пытается, и я подозреваю, что это может быть обязательной проблемой … даже если я считаю, что я связал это правильно и зарегистрировал его в качестве поставщика услуг.
Я должен упомянуть, что я взял этот пример из «Реализации Ларавела» Криса Фидао, и он почти идентичен!
Это первая пара строк моего класса формы:
namespace Project\Backend\Service\Form\Job;
use Project\Backend\Service\Validation\ValidableInterface;
use Project\Backend\Repo\Job\JobInterface;
class JobForm {
/**
* Form Data
*
* @var array
*/
protected $data;
/**
* Validator
*
* @var \Project\Backend\Form\Service\ValidableInterface
*/
protected $validator;
/**
* Job repository
*
* @var \Project\Backend\Repo\Job\JobInterface
*/
protected $job;
public function __construct(ValidableInterface $validator, JobInterface $job)
{
$this->validator = $validator;
$this->job = $job;
}
Это первые несколько строк моего класса валидатора:
namespace Project\Backend\Service\Form\Job;
use Project\Backend\Service\Validation\AbstractLaravelValidator;
class JobFormValidator extends AbstractLaravelValidator {
// Includes some validation rules
Это абстрактный валидатор:
namespace Project\Backend\Service\Validation;
use Illuminate\Validation\Factory;
abstract class AbstractLaravelValidator implements ValidableInterface {
/**
* Validator
*
* @var \Illuminate\Validation\Factory
*/
protected $validator;
/**
* Validation data key => value array
*
* @var Array
*/
protected $data = array();
/**
* Validation errors
*
* @var Array
*/
protected $errors = array();
/**
* Validation rules
*
* @var Array
*/
protected $rules = array();
/**
* Custom validation messages
*
* @var Array
*/
protected $messages = array();
public function __construct(Factory $validator)
{
$this->validator = $validator;
}
Это код, где я связываю все это с приложением:
namespace Project\Backend\Service\Validation;
use Illuminate\Support\ServiceProvider;
use Project\Backend\Service\Form\Job\JobFormValidator;
class ValidationServiceProvider extends ServiceProvider {
public function register()
{
$app = $this->app;
$app->bind('Project\Backend\Service\Form\Job\JobFormValidator', function($app)
{
return new JobFormValidator($app['validator']);
});
}
}
Затем это регистрируется в app / config / app.php:
.....
'Project\Backend\Service\Validation\ValidationServiceProvider',
....
Наконец, это первые несколько строк моего контроллера:
use Project\Backend\Repo\Job\JobInterface;
use Project\Backend\Service\Form\Job\JobForm;
class JobController extends \BaseController {
protected $jobform;
function __construct(JobInterface $job, JobForm $jobform)
{
$this->job = $job;
$this->jobform = $jobform;
}
Вы должны указать Laravel, какой экземпляр он должен использовать для определенного интерфейса, при внедрении его в конструктор с помощью подсказки типа.
Вы делаете это с помощью bind()
метод (например, у вашего поставщика услуг)
$app->bind('JobInterface', 'Job'); // Job being the class you want to be used
Я настоятельно рекомендую вам посмотреть видео здесь где Тейлор Отвелл, создатель Laravel, объясняет это и некоторые другие вещи.
Сначала вам нужно связать с помощью
/app/Providers/AppServiceProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
$this->app->bind('JobInterface', 'Job');
}
}
Как только вы завершите это изменение
Запустите обновление композитора