service provider
- Registration methods
- bindings and singletons Features
- Bootstrap method
- Dependency injection of startup methodRegistered Service Provider
- Delayed Provider
Service Provider
Introduction
Service providers are the hub for all Laravel applications. Your application, as well as the core Laravel services bootstrapped through the server, are bootstrapped through service providers.
But, what does "guidance" mean? Usually, ours can be understood as Registration, such as registering service container bindings, event listeners, middleware, and even routing. Service providers are central to configuring applications.
When you open Laravel's config/app.php
file, you will see the providers
array. The contents of the array are the classes of all service providers to be loaded by the application. Of course, there are many "lazy" providers, which are not loaded on every request, but only when their services are actually needed.
In this article you will learn how to write your own service provider and register it into your Laravel application
Writing service providers
All service providers will inherit the Illuminate\Support\ServiceProvider
class. Most service providers contain a register
and a boot
method. In the register
method, you just bind the thing to the service container. Do not try to register any listeners, routes, or any other functions in the register
method.
Use the Artisan command line tool to generate one through the make:provider
command. New provider:
php artisan make:provider RiakServiceProvider
Register method
As mentioned above, in the register
method, you just need Bind the service into the service container. Do not try to register any listeners, routes, or any other functionality in the register
method. Otherwise, you might accidentally use services from a service provider that hasn't been loaded yet.
Let's look at a basic service provider. In any service provider method, you always access the service container through the $app
property:
<?php namespace App\Providers;use Riak\Connection; use Illuminate\Support\ServiceProvider; class RiakServiceProvider extends ServiceProvider{ /** * 在服务容器里注册 * * @return void */ public function register() { $this->app->singleton(Connection::class, function ($app) { return new Connection(config('riak')); }); } }
This service container simply defines a register
method, and Use this method to define a Riak\Connection
interface in the service container. If you don't understand how a service container works, check out its documentation.
bindings
and singletons
If your service provider registers many simple bindings, you may want to use bindings
and singletons
properties instead of manually registering each container binding. When the service provider is loaded by the framework, these properties will be automatically checked and the corresponding bindings will be registered
<?php namespace App\Providers; use App\Contracts\ServerProvider; use App\Contracts\DowntimeNotifier; use Illuminate\Support\ServiceProvider; use App\Services\PingdomDowntimeNotifier; use App\Services\DigitalOceanServerProvider; class AppServiceProvider extends ServiceProvider{ /** * 设定所有的容器绑定的对应关系 * * @var array */ public $bindings = [ ServerProvider::class => DigitalOceanServerProvider::class, ]; /** * 设定所有的单例模式容器绑定的对应关系 * * @var array */ public $singletons = [ DowntimeNotifier::class => PingdomDowntimeNotifier::class, ]; }
Bootstrap method
If we want How to register a view composer with a service provider? This requires using the boot
method. This method will not be called until all service providers are registered, which means that we can access all other services registered by the framework:
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class ComposerServiceProvider extends ServiceProvider{ /** * 启动所有的应用服务。 * * @return void */ public function boot() { view()->composer('view', function () { // }); } }
Dependency injection of startup method
You can set type hints for the service provider's boot
methods. The service container will automatically inject the dependencies you need:
use Illuminate\Contracts\Routing\ResponseFactory; public function boot(ResponseFactory $response){ $response->macro('caps', function ($value) { // }); }
Register service provider
All service providers are through configuration filesconfig/app.php
Register. This file contains a providers
array that lists the names of all service providers. By default, all core service providers are listed. These service providers start Laravel core components, such as mail, queue, Caching and so on.
To register a provider, just add it to the array:
'providers' => [ // 其他服务提供者 App\Providers\ComposerServiceProvider::class,],
Deferred Provider
If your The service provider is only registered in the service container. You can choose to delay loading the binding until the registered service is really needed. Lazy loading of such a provider will improve the performance of the application. Because it doesn't load from the file system on every request.
Laravel compiles and saves a list of all services provided by deferred service providers, along with the names of their service provider classes. Therefore, Laravel will only load the service provider if you are trying to resolve one of the services.
To delay loading the provider, you need to implement the \Illuminate\Contracts\Support\DeferrableProvider
interface and configure a provides
method. This provides
method returns the service container binding registered by this provider:
<?php namespace App\Providers; use Riak\Connection; use Illuminate\Support\ServiceProvider; use Illuminate\Contracts\Support\DeferrableProvider; class RiakServiceProvider extends ServiceProvider implements DeferrableProvider{ /** * 注册服务提供者。 * * @return void */ public function register() { $this->app->singleton(Connection::class, function ($app) { return new Connection($app['config']['riak']); }); } /** * 获取由提供者提供的服务。 * * @return array */ public function provides() { return [Connection::class]; } }