Ground Sunlight

Windowsで作る - PHPプログラミングの開発環境

ユーザ用ツール

サイト用ツール


サイドバー

メインメニュー

XAMPP アレンジ

IED

WSL2

道具箱

リポジトリ編

フレームワーク編

公開ソフトウェア

メタ
リンク


このページへのアクセス
今日: 4 / 昨日: 22
総計: 795

apricot:usage:ja:provider

文書の過去の版を表示しています。


編集中

Apricot サービスプロバイダー

y2sunlight 2020-07-29

Apricot Document に戻る

目次


Apricotでは、DIコンテナーに League/Container を使用しています。League/Container ではサービスプロバイダーを使い、サービスをシングルトンとして登録することができます。

Apricotのスケルトンでは、サービスプロバイターの簡単な例題を提供しています。


DIコンテナ

DIコンテナを使用することで、サービスとその依存関係を登録しておいて後で取得することができます。例えば、サービスAがモデルBとモデルCを使用しているような場合、サービスコンテナにサービスAを要求すると、自動的にモデルBとCを生成し、それらをサービスAのコンストラクタに与えてサービスAを生成してくれます。これがDIコンテナです。

ここでは、League/Container の慣例に従いDIコンテナと呼んでいますが、これはサービスコンテナと呼ばれることもあります。


Providerクラス

サービスプロバイターは、アプリケーション内の全てのDIコンテナを登録し整理する方法を提供してくれます。また、サービスプロバイダーではサービスが取得された時点で遅延登録されるため、アプリケーションのパフォーマンス向上にも寄与します。

Apricotのスケルトンではサービスプロバイターとして、League/Container が提供している基本サービスプロバイダークラス( AbstractServiceProvider )を拡張した App\Provider クラスを定義しています。このクラスは、/your-project/app に配置されています。

以下にApricotのスケルトンで初期実装されているProviderクラスの抜粋を示します。

/your-project/app

Provider.php
<?php
namespace App;
 
use League\Container\ServiceProvider\AbstractServiceProvider;
 
/**
 * Provider class for service
 */
class Provider extends AbstractServiceProvider
{
    /**
     * 提供される配列は、サービスがこのサービスプロバイダーによって提供されていることをコンテナーに知らせるための方法です。
     * このサービスプロバイダーを介して登録されるすべてのサービスには、この配列にエイリアスが追加されている必要があります。
     * そうでない場合は無視されます。
     *
     * @var array
     */
    protected $provides = [
        // Sample
        'SampleService',
    ];
 
    /**
     * ここでマジックが起こります。メソッド内でコンテナーにアクセスして必要なものを登録または取得できますが、
     * このメソッド内に登録されたすべてのエイリアスは '$provides' 配列で宣言する必要があります。
     */
     public function register()
    {
        // Sample
        $this->getContainer()
             ->add('SampleService', \App\Services\SampleService::class, true)
             ->addArgument('User')
        ;
 
        $this->getContainer()->add('User', \App\Models\User::class);
     }
}

スケルトンではサービスのサンプルとして SampleService クラスを提供しています。このクラスはコンストラクタにUser モデルを与えて作ります。

SampleService クラスをサービスプロバイターに登録するには、コンテナのadd() メソッドを使用し、その引数は、エイリアス名、登録するクラス、そしてフラグです。フラグがtrueの場合、このクラスはシングルトンとして動作します。addArgument() メソッドは登録するクラスのコンストラクタに与える引数を定義します。addArgument() メソッドで定義した引数もまたサービスプロバイターに登録しておく必要があります。

モデルやサービスをサービスプロバイターに登録する場合は、上例に習って適宜追加して下さい。League/Container のサービスプロバイダーについての詳細はこちらをご覧ください。


App\Foundation\Containerクラス

App\Foundation\Containerクラスは、\League\Container\Container クラスを生成し、Apricotのサービスプロバイダー(Provider)を登録したクラスで、シングルトンとして動作します。

サービスの使用者は、App\Foundation\Containerが持っている PSR-11 に準じた get()has() を使ってサービスを利用することができます。

使用法: Container::{メソッド}

メソッド機能
mixed get(string $id)識別子idでコンテナのエントリを検索して返します。
bool has(string $id)コンテナが指定された識別子idのエントリを返すことができる場合はtrueを返します。

/apricot/app/Foundation

Container.php
<?php
namespace App\Foundation;
 
use Apricot\Foundation\Singleton;
use App\Provider;
 
/**
 * Container class for service
 *
 * @method static Container getInstance() Gets the Container instance.
 * @method static mixed get(string $id) Finds an entry of the container by its identifier and returns it.
 * @method static bool has(string $id) Returns true if the container can return an entry for the given identifier.
 */
class Container extends Singleton
{
    /**
     * Create Container instance.
     * @return \League\Container\Container
     */
    protected static function createInstance()
    {
        $container = new \League\Container\Container;
        $container->addServiceProvider(new Provider());
        return $container;
    }
}


DIコンテナの使用例

スタブコントローラ

DIコンテナをテストするために、スタブコントローラを以下のように修正します。

/apricot/app/Controllers

StubController.php
<?php
namespace App\Controllers;
 
use App\Foundation\Container;
use App\Foundation\Controller;
 
/**
 * Stub Controller
 */
class StubController extends Controller
{
    /**
     * Index Page for this controller.
     *
     * @return \Apricot\Foundation\Response
     */
    public function index(int $no=null)
    {
        $title = "Stub {$no}";
 
        /*
         * Example for Container
         * @var \App\Models\User $user
         */
        $user = Container::get('user');
        $userCount = count($user->findAll());
        $messages[] = "Number of registered users : {$userCount}";
 
        return render('stub',['title'=>$title,'messages'=>$messages]);
    }
}
  • Container::get('user') でユーザモデルを生成します。
  • ユーザモデルの findAll() を実行して全ユーザのリストを取得します。
  • ユーザ数を表示するために、テンプレート変数 $messages をセットします。


コメント

コメントを入力. Wiki文法が有効です:
 
apricot/usage/ja/provider.1598687401.txt.gz · 最終更新: 2020/08/29 16:50 by y2sunlight