I read articles about Laravel service providers and containers. I understand that Service Provider is a way to organize service objects bindings to the IoC, useful when your application is fairly large.
But then I looked up in the ready service provider folder and saw this AppServiceProvider
provider and the register method if it:
public function register()
{
$this->app->bind(
'Illuminate\Contracts\Auth\Registrar',
'App\Services\Registrar'
);
}
Why do they bind the namespaces to the IoC, when you can do App::make
to get it anyway without binding these namespaces? I thought that I understood how that business works until I saw this piece of code.
Why did they do that? Thanks!
Binding Scoped SingletonsThe scoped method binds a class or interface into the container that should only be resolved one time within a given Laravel request / job lifecycle.
Service providers are the central place to configure your application. If you open the config/app. php file included with Laravel, you will see a providers array. These are all of the service provider classes that will be loaded for your application.
Service container is where your services are registered. Service providers provide services by adding them to the container.
Namespaces can be defined as a class of elements in which each element has a unique name to that associated class. It may be shared with elements in other classes.
For example, u want to use some file storage in your aplication
App::bind( 'MyApp/FileStorage', function(){
return new AmazonFileStorage;
});
Or
App::bind( 'MyApp/FileStorage', 'AmazonFileStorage');
First parameter for the bind method is a unique id to bind to the container, the second parameter is callback function to be executed each time we resolve the FileStorage class, we can also pass a string representing class name.
So maybe later you want to use other file storage service. You will need only to change your binding as in your application u will use "MyApp/FileStorage"
App::bind( 'MyApp/FileStorage', 'SystemFileStorage');
$this->app->bind(
'Illuminate\Contracts\Auth\Registrar',
'App\Services\Registrar'
);
There is interface Registrar :
<?php namespace Illuminate\Contracts\Auth;
interface Registrar {
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
public function validator(array $data);
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return User
*/
public function create(array $data);
}
And service Registrar
<?php namespace App\Services;
use App\User;
use Validator;
use Illuminate\Contracts\Auth\Registrar as RegistrarContract;
class Registrar implements RegistrarContract {
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
public function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return User
*/
public function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
}
And then in 'App\Http\Controllers\Auth\AuthController' is injected
And the concept behind this is "Binding Interfaces To Implementations" You can read about it in official laravel 5 documantation http://laravel.com/docs/5.0/container#binding-interfaces-to-implementations and if it doesn't help, ask :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With