码源 / 容器
支持应用程序模块的简单依赖注入容器
3.0.1
2022-01-25 12:25 UTC
Requires
- php: ^8.1
- psr/container: ^2
Requires (Dev)
- ext-json: *
- ext-pdo: *
- infection/infection: ^0.26
- phpbench/phpbench: ^1
- phpunit/phpunit: ^9
Provides
README
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', ...]);
待续...
代码质量
vendor/bin/infection --threads=4 vendor/bin/phpbench run --report=default vendor/bin/phpunit
许可
代码在 3-Clause BSD 许可证 的条款下分发。