fideloper / Implementing-Laravel

Companion application to the e-book Implementing Laravel
173 stars 40 forks source link

Validation as a Service chapter needs a service provider class #14

Closed fideloper closed 10 years ago

fideloper commented 10 years ago

Something like this is needed at the end of the Validation as a Service chapter. The next chapter includes one that is specific to the Form class, but users who don't go to that extent in their code is missing an important piece of information to make it work.

<?php namespace Impl\Service\Validation;

use Illuminate\Support\ServiceProvider;
use Impl\Service\Validation\SomeValidator;

class ValidationServiceProvider extends ServiceProvider {

    /**
     * Register the binding
     *
     * @return void
     */
    public function register()
    {
        $app = $this->app;

        $app->bind('Impl\Service\Validation\SomeValidator', function($app)
        {
            return new SomeValidator( $app['validator'] );
        });
    }

}
abfan1127 commented 10 years ago

Which class are we binding? If we have more than one validator, which validator are we binding? Why don't we bind the interface? Sorry, I'm still a bit new to Laravel.

epcliff commented 10 years ago

Hi Chris. I need to bind ValidableInterface, right?

fideloper commented 10 years ago

If you bind to the interface here, then that means you're likely type hinting the interface in your Form class, right?

In that situation, how does Laravel know which implementation of the Validation class to use? It doesn't.

So here we're actually telling Laravel that when concrete class SomeValidator is asked for, return SomeValidator and pass it $app['validator']. We're just using the Container's convenient class resolution.

You don't need to bind to an interface or abstract class!

This is a bit awkward, admittedly, but it's a convenient way to let the code instantiate your (concrete) Validator classes for you.

epcliff commented 10 years ago

Thanks so much for replying sooner Chris. Yes I'm type hinting the ValidableInterface in my Form class just like in your book. So I added ValidationServiceProvider above and I see your point now but I'm still getting this error: Target [IAPON\Service\Validation\ValidableInterface] is not instantiable. How will I resolve this?

fideloper commented 10 years ago

Sounds like IAPON\Service\Validation\ValidableInterface is properly getting bound to anything. Perhaps you created the Service Provider but didn't' register it in in app/config.php ?

On Tue, Mar 11, 2014 at 10:15 AM, epcliff notifications@github.com wrote:

Thanks so much for replying sooner Chris. Yes I'm type hinting the ValidableInterface in my Form class just like in your book. So I added ValidationServiceProvider above and I see your point now but I'm still getting this error: Target [IAPON\Service\Validation\ValidableInterface] is not instantiable. How will I resolve this?

Reply to this email directly or view it on GitHubhttps://github.com/fideloper/Implementing-Laravel/issues/14#issuecomment-37299617 .

epcliff commented 10 years ago

No I registered it and did composer dump-autoload. I really appreciate you for helping me out. Thanks.

Here's my ValidationServiceProvider:

use Illuminate\Support\ServiceProvider;
use IAPON\Service\Form\RoleFormValidator;

class ValidationServiceProvider extends ServiceProvider {

public function register()
{
    $app = $this->app;

    $app->bind('IAPON\Service\Form\RoleFormValidator', function($app)
    {
        return new RoleFormValidator($app['validator']);
    });
}
}

RoleForm class:

use IAPON\Service\Validation\ValidableInterface;
use IAPON\Repo\Role\RoleInterface;

class RoleForm {
    protected $data;
    protected $validator;
    protected $role;

    public function __construct(ValidableInterface $validator, RoleInterface $role) {
        $this->validator = $validator;
        $this->role = $role;
    }
}

Am I still going to inject ValidableInterface in my RoleForm __construct or just RoleFormValidator? Sorry, this part I obviously have a hard time understanding. Thanks in advance.