一.编写一个服务提供类

class Test
{
	public function hello()
	{
		echo 'hello world';
	}

}

  

二.服务提供者

1.生成

artisan make:provider TestServiceProvide

  

2.生成后的代码:

class TestServiceProvide extends ServiceProvider
{
	/**
	* Bootstrap the application services.
	*
	* @return void
	*/
        public function boot()
	{
		//
	}

	/**
	* Register the application services.
	*
	* @return void
	*/
	public function register()
	{
		
	}
}

  

3.在register中可以绑定服务和对应的类,或者将一个接口绑定到一个类,有三种方法:

a.绑定一个实例:

$instance = new Test();
$this->app->instance('TestServiceProvider', $instance);

  

b.bind

如果不需要自动依赖,也可以new Test;使用app()帮助函数解决了自动依赖

$this->app->bind('TestServiceProvider', function($app) {
	return app(Test::class);
});

  

或者

$this->app->bind('TestServiceProvider', Test::class);

  

如果将bind的第三个参数设置为true,即为共享模式;也就是绑定的服务对应的类是一个单例模式;默认为false

 

c.绑定一个单例:

$this->app->singleton('TestServiceProvider', Test::class); //也可以使用闭包或new Test

  

以上绑定中,TestServiceProvider就是这个服务的名字,后面的指明了有那个类来提供服务.这个服务的名字可以随便取,调用服务名字的时候,再去取到对应的类实现.如果这个服务名是一个接口,那么就可以实现依赖注入.

 

三.注册服务

1.在app/config.php下的providers数组中,添加

Test\Providers\TestServiceProvide::class

  

2.在providers中的AppServiceProvider.php的register方法中添加(这种方式更适合按需加载服务提供者):

$this->app->register(TestServiceProvide::class);

  

四.延迟绑定服务

如果服务不是每次加载都需要,可以提供延迟绑定,在需要的时候再绑定

class TestServiceProvide extends ServiceProvider
{
	protected $defer = true;

	/**
	* Bootstrap the application services.
	*
	* @return void
	*/
        public function boot()
	{
		//
	}

	/**
	* Register the application services.
	*
	* @return void
	*/
	public function register()
	{
		$this->app->singleton('TestServiceProvider', Test::class);
	}

	public function provides()
	{
		return ['Test'];
	}
}

  

五.控制器或其他地方调用

1.依赖注入


2.app('TestServiceProvider')

 

六.门面(Facades)

1.门面简化了服务在应用的调用方式,以一种看起来像是静态调用的方式来简化调用,如
Auth::id(),Auth::check()等;

2.我们看看来如何建立一个门面

a.建立一个门面类,继承Facade,重写getFacadeAccessor方法

class TestFacade extends Facade
{
    protected static function getFacadeAccessor()
    {
	// 返回一个服务提供者
        return 'TestServiceProvider';
    }

}

  

b.在app/config.php的aliases添加:

...
'MyTest' => Test\Facades\TestFacade::class, //MyTest是门面的名字,随便取

  

3.使用

use MyTest;
..............
..............

.........
	MyTest::hello();
.........

  

需要说明的是门面对应的服务提供者将实现的是一个单例服务.

 

总结:

总体而言,如果你不做第三方应用,不做全局的操作,不做接口到类的依赖注入.其实没有必要使用服务提供者.而门面仅仅是对服务调用方式的一种包装罢了.