服务提供者

 


 

定义

服务提供者就是,当前应用需要哪些服务/组件,我们就在服务提供者里面定义哪些服务/组件,方便在程序里面直接使用,解决了类与类之间的耦合

 

存放位置

 

可以在任意位置建立服务提供者,我们推荐在 /common/provider 目录下新建服务提供者类,服务提供者类必须继承Timo\Support\ServiceProvider,
我们只需在类的register方法里面注册服务即可,看下面的例子
服务提供者可以是多个,我们可以使用服务提供者下面的$di(服务容器实例)属性来注册服务

 

新建服务提供者

 

创建一个空的服务提供者CommonProvider,意思就是没有注册任何一个服务,路径:/common/provider/CommonProvider

 

<?php
namespace common\provider;

class CommonProvider extends ServiceProvider
{
    public function register()
    {
        
    }
}

 

注册服务

 

注册服务只需在register方法里面注册服务即可,注册方式有很多种

 

方式一,普通注册,通过get获取服务时,获取到的都是全新服务实例

 

$this->di->bind();

 

方式二,单例模式注册,通过get获取服务时,获取到的都是同一个服务器实例

 

$this->di->singleton();

 

方式三,注册一个服务器实例

 

$this->di->instance();

 

举例说明

 

<?php
namespace common\provider;

use lib\markdown\Markdown;
use Timo\Support\ServiceProvider;

class CommonProvider extends ServiceProvider
{
    public function register()
    {
        $this->di->bind([Car::class => 'car'], function() {
            return new Car();
        });
        
        $this->di->singleton('markdown', Markdown::class);
        $this->di->singleton('markdown', 'lib\markdown\Markdown');
        
        $this->bind(['lib\pay\Client' => 'pay'], function($di) {
            $car = $di->get('car');
            return new Client($car);
        });
    }
}

 

上面我们注册了一个名为car的服务,并且是以单例的模式注册的,可以在register方法里面注册多个服务

 

服务别名

 

namespace common\provider;

use lib\markdown\Markdown;
use Timo\Support\ServiceProvider;

class CommonProvider extends ServiceProvider
{
    public function register()
    {
        //说明 Markdown::class 等于 'lib\markdown\Markdown' , 服务别名就是markdown
        $this->di->singleton([Markdown::class => 'markdown'], Markdown::class);
    }
}

 

注册服务提供者

 

 

 

我们要告诉框架有哪些服务提供者

 

可以在配置文件中providers项定义服务提供者,可注册多个
'providers' => [
    app\provider\CommonProvider::class,
    app\provider\PayProvider::class,
    app\provider\Ossprovider::class
]

 

怎样获取服务容器实例

我们要在其它类里面使用服务容器,该怎么获取呢?
$di = App::di();
比如,我们要在控制器里面使用,我们可以放到所有控制器的基类里面,比如Base、Common控制器

 

namespace app\web\controller;


use Timo\Core\Controller;

class Base extends Controller
{
    protected $di;

    public function __construct()
    {
        parent::__construct();

        $this->di = App::di();
    }
}

 

然后,我们就可以在其它控制器里面方便的使用了

 

php
namespace app\web\controller;


use app\web\model\DocumentModel;
use lib\markdown\Markdown;
use Timo\Core\Exception;
use Timo\Core\Request;

class Document extends Common
{
    /**
     * 文档详情页
     *
     * @param int $id
     * @return string
     * @throws Exception
     */
    public function show($id = 0)
    {
        $id = (int) $id;
        if ($id <= 0) {
            throw new Exception('文档ID不能小于零');
        }

        //获取文档标题
        $document = (new DocumentModel())->getDocument($id);
        if (!$document) {
            throw new Exception('文档'.$id.'不存在');
        }

        //获取文档内容
        /**
         * @var $markdown Markdown
         */
        $markdown = $this->di->get('markdown');
        $doc_html = $markdown->makeHtmlFragment('document', $id, false);

        $this->assign('title', $document['title']);
        $this->assign('doc', $doc_html);

        return $this->render();
    }
}