neat/service

Neat 服务组件

0.4.0 2022-02-08 15:51 UTC

This package is auto-updated.

Last update: 2024-09-14 19:04:16 UTC


README

Stable Version Build Status codecov

Neat 服务组件提供了一种干净且富有表达力的 API,以便您的应用程序提供、访问和注入服务和其他依赖项。实现了 PSR-11 容器接口,以实现最佳互操作性。

入门指南

要安装此包,请在命令行中运行 composer

composer require neat/service

服务容器

包含的服务容器允许您使用工厂和预设实例来注册和检索服务实例。

<?php

// First whip up a new container
$container = new Neat\Service\Container();

// Then teach it how to create a service
$container->set(PDO::class, function () {
    return new PDO('sqlite:memory');
});

// And retrieve it using has and get methods
if ($container->has(PDO::class)) {
    $pdo = $container->get(PDO::class);
}

服务别名

要引用服务,您不必总是使用完整的类名。这不仅是为了方便,还可以将您的代码与其依赖实现解耦。

<?php

/** @var Neat\Service\Container $container */

// Suppose we want to access the Neat\Database\Connection service by an alias
$container->alias(PDO::class, 'db');

// Now we can access a service by its db alias
$container->set('db', function() {
    return new PDO('sqlite:memory');
});

$db = $container->get('db');

您还可以使用别名通过接口名称使服务可用。这在使用依赖注入时将非常有用。

服务提供者

为了帮助您设置多个服务,您可以定义一个服务提供者,它不过是一个具有公共服务工厂方法的对象。

<?php

/** @var Neat\Service\Container $container */

class Services
{
    public function now(): DateTime
    {
        return new DateTime('now');
    }

    // Notice how this depends on the service above, the container will
    // automatically resolve this dependency for us.
    public function clock(DateTime $time): Example\Clock
    {
        return new Example\Clock($time);
    }
}

// Now register the service provider
$container->register(new Services());

// To get my clock you would simply use
$container->get(Example\Clock::class);

// Or access the service through its alias (the name of the method)
$container->get('clock');

依赖注入

容器还可以使用自动装配技术为您创建对象并调用方法。这意味着它将根据方法签名和参数类型自动检测、解析和注入依赖项。

<?php

/** @var Neat\Service\Container $container */

// Assuming your container can produce a PDO and Clock object instance
class BlogController
{
    private $db;

    public function __construct(PDO $db)
    {
        $this->db = $db;
    }

    public function getPosts(Example\Clock $clock, string $tag = null) {
        // ...
    }
}

// You'd create a controller and automatically inject the PDO object
$blog = $container->create(BlogController::class);

// Call the getPosts method and have it receive the Clock object
$posts = $container->call([$blog, 'getPosts']);

// You can combine these two calls into one invocation
$posts = $container->call('BlogController@getPosts');

// And pass any arguments you wish to specify or override
$sportsPosts = $container->call('BlogController@getPosts', ['tag' => 'sports']);