siganushka / registry-contracts

注册模式抽象集。

0.1.1 2022-06-08 08:15 UTC

This package is auto-updated.

Last update: 2024-09-07 10:04:16 UTC


README

注册模式抽象集。

安装

$ composer require siganushka/registry-contracts

用法

// ./src/Channel/ChannelInterface.php

interface ChannelInterface
{
    public function methodA(): string;
    public function methodB(): int;
 
    // ...
}

// ./src/Channel/FooChannel.php

class FooChannel implements ChannelInterface
{
    // ...
}

// ./src/Channel/BarChannel.php

class BarChannel implements ChannelInterface
{
    // ...
}
use Siganushka\Contracts\Registry\ServiceRegistry;

$registry = new ServiceRegistry(ChannelInterface::class);
$registry->register('foo', new FooChannel());
$registry->register('bar', new BarChannel());

$registry->get('foo');      // return instanceof FooChannel
$registry->has('bar');      // return true
$registry->all();           // return array of instanceof ChannelInterface
$registry->getServiceIds(); // return ['foo', 'bar']

使用别名

// ./src/Channel/FooChannel.php

use Siganushka\Contracts\Registry\ServiceRegistry;
use Siganushka\Contracts\Registry\AliasableInterface;

class FooChannel implements ChannelInterface, AliasableInterface
{
    public function getAlias(): string
    {
        return 'foo';
    }

    // ...
}

$channels = [
    new FooChannel()
];

// the second argument is type iterable of $services 
$registry = new ServiceRegistry(ChannelInterface::class, $channels);

$registry->get('foo');      // return instanceof FooChannel
$registry->has('foo');      // return true
$registry->all();           // return array of instanceof ChannelInterface
$registry->getServiceIds(); // return ['foo']

使用 symfony 标记服务

// ./src/Channel/ChannelRegistry.php

class ChannelRegistry extends ServiceRegistry
{
    public function __construct(iterable $channels)
    {
        parent::__construct(ChannelInterface::class, $channels);
    }
}
// ./config/services.yaml

services:
    _instanceof:
        App\Channel\ChannelInterface:
            tags: [ app.channel ]

    App\Channel\ChannelRegistry:
        arguments: [ !tagged_iterator app.channel ]
// ./src/Controller/BazController.php

class BazController extends AbstractController
{
    public function index(ChannelRegistry $registry)
    {
        $foo = $registry->get(FooChannel::class);
        // or $registry->get('foo') if using alias
        // $foo is instanceof FooChannel
    }
}

更多详情: https://symfony.com.cn/doc/current/service_container/tags.html#reference-tagged-services

测试

$ php vendor/bin/simple-phpunit --debug