码源/容器

支持应用程序模块的简单依赖注入容器

3.0.1 2022-01-25 12:25 UTC

This package is auto-updated.

Last update: 2024-08-25 22:50:07 UTC


README

CI Latest Stable Version Minimum PHP Version: 8.1

koded/container 是一个面向对象的应用程序引导和连接库。换句话说,Koded\DIContainer 实现了一个名为 依赖倒置 的设计模式。DIP 的主要原则是将行为与依赖解析分离。

composer require koded/container

示例

让我们看看一个具有以下内容的博客应用程序:

  • 数据库存储库的接口及其相应的实现
  • 一个共享的 PDO 实例
  • 用于获取博客内容的服务类
  • 映射请求方法的处理类
use PDO;

interface PostRepository {
    public function findBySlug(string $slug);
}

interface UserRepository {
    public function findById(int $id);
}

class DatabasePostRepository implements PostRepository {
    private $pdo;
    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }
    public function findBySlug(string $slug) {
        // $this->pdo ...
    }
}

class DatabaseUserRepository implements UserRepository {
    private $pdo;
    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }
    public function findById(int $id) {
        // $this->pdo ...
    }
}

在某处我们可能有一个使用依赖存储库的服务类

class PostService {
    private $post, $user;
    public function __construct(PostRepository $post, UserRepository $user) {
        $this->post = $post;
        $this->user = $user;
    }

    // a service method that uses the post and user repository instances
    public function findBlogPostBySlug(string $slug) {
        $post = $this->post->findBySlug($slug);
        $user = $this->user->findById($post->userId());
        // ... do something with the results, create a result data structure...
    }
}

然后在某处我们可能有一个请求处理程序/控制器,它要求自己的依赖项

class BlogHandler {
    public function get(ServerRequestInterface $request, PostService $service): ResponseInterface {
        $slug = slugify($request->getUri()->getPath());
        $post = $service->findBlogPostBySlug($slug);

        // some PSR-7 compatible response object
        return new ServerResponse($post);
    }
}

连接所有事物

这是引导/连接应用程序模块(或容器的“配置”类),在这里所有已知的依赖项都被绑定和共享

class BlogModule implements DIModule {
    public function configure(DIContainer $container): void {
        // bind interfaces to concrete class implementations
        $container->bind(PostRepository::class, DatabasePostRepository::class);
        $container->bind(UserRepository::class, DatabaseUserRepository::class);
        $container->bind(ServerRequestInterface::class, /*some PSR-7 server request class name*/);
        
        // share one PDO instance
        $container->singleton(PDO::class, ['sqlite:database.db']);
    }
}

最后,在分发文件中,我们处理请求

// index.php

// (resolved through an HTTP router or other means)
$handler = BlogHandler::class;
$method = 'get';

// by invoking the container
$response = (new DIContainer(new BlogModule))([$handler, $method]);

// we have a `$response` object to output the content
// ex. `echo $response->getBody()->getContents();`

容器实现了 __invoke() 方法,因此实例可以用作函数

$container('method', ['arg1', 'arg2', ...]);

待续...

代码质量

Code Coverage Scrutinizer Code Quality Infection MSI

vendor/bin/infection --threads=4
vendor/bin/phpbench run --report=default
vendor/bin/phpunit

许可

Software license

代码在 3-Clause BSD 许可证 的条款下分发。