过氧化物 / 容器
Peroxide 容器,一个简单的工厂驱动的 PSR-11 依赖注入容器,无依赖和低功能。
v1.2.1
2024-04-11 21:52 UTC
Requires
- php: ^8.1 || ^8.2
- psr/container: ^2.0
Requires (Dev)
- phpunit/phpunit: ^10.3
- squizlabs/php_codesniffer: ^3.9
README
Peroxide/容器
一个简单的依赖注入容器,设计用于与 API 一起使用,遵循 PSR-11 标准。它具有最小的功能,并且独立运行,无外部依赖。
我们的理念
我们热衷于与尽可能干净和简单的组件一起工作。 Peroxide\Container 是从类似 Laminas\ServiceManager、Pimple 和 PHP-DI 的库中汲取灵感而融合而成的。
我们的巨大优势是没有任何外部依赖。所有配置都通过 PHP 代码使用数组配置文件来实现。你只需要确保你的框架支持 PSR-11,设置配置,然后你就可以开始你的编码之旅了。
如何使用它
安装
composer require peroxide/container
开始你的旅程
Peroxide\Container 完全符合 PSR-11 标准,并提供以下方法
# From PSR-11 public function get(string $id): object; public function has(string $id): bool; # From our interface SetDependency public function set(string $id, callable $factory): void; public function setInvokableClass(string $id, string $invocableClass): void;
将你的配置作为 数组 创建
<?php use Peroxide\DependencyInjection\Container; $config = [ YourDependencyName::class => fn() => new YourDependencyName(), YourDependency::class => YourDependencyFactoryClass::class, // should be invokable class ConcreteClass::class => new ConcreteClassFactory(), // Or passing as reference string ConcreteClass::class => ConcreteClassFactory::class ]; $container = new Container($config); // how to get dependencies $container->get(YourDependencyName::class); $container->get(YourDependency::class); $container->get(ConcreteClass::class);
创建你的工厂类
use Psr\Container\ContainerInterface; use Peroxide\DependencyInjection\Interfaces\ContainerFactory; class ConcreteClassFactory implements ContainerFactory { public function __invoke(ContainerInterface $container): ConcreteClass { // config your dependency injection here // you can compose your dependency // return new ParentDependency($container->get(DependencyChild::class)); return new ConcreteClass(); } }
在获取容器实例后,也可以单独设置依赖项
use Peroxide\DependencyInjection\Container; $container = new Container(); $container->set(DependencyPath::class, fn() => new DependencyInstance());
如果依赖项不存在,则将其创建;如果存在,则由新的工厂替换。
更多配置
要处理容器内的依赖注入,你可以轻松使用 箭头函数
来组合你的依赖项。
$container = new Container([ // Dependency parent with dependency child // all dependencies should be involved by a Closure(function() or fn()) Dependency::class => fn() => new Dependency(), ComponentThatHasAnotherDependency::class => function($container) { return new ComponentThatHasAnotherDependency( $container->get(Dependency::class) ); }, // or simply ComponentThatHasAnotherDependency::class => fn($c) => new ComponentThatHasAnotherDependency($c->get(Dependency::class)), // more complex injections ComponentThatHasTwoDeps::class => fn($c) => new ComponentThatHasTwoDeps( $c->get(Dependency::class), $c->get(AnotherDependency::class), ) ]);
你还可以使用扩展运算符来组合配置,如示例所示
use Peroxide\DependencyInjection\Container; # on 'dependencies.php' config file $config1 = [ ... ]; $config2 = [ ... ]; return [...$config1, ...$config2]; // ------------------- $config = require __DIR__ . '/dependencies.php'; $container = new Container($config);
如何处理单例?
只需使用 Singleton 可调用类,以下是一个示例
use Peroxide\DependencyInjection\Container; use Peroxide\DependencyInjection\Invokables\Singleton; $container = new Container([ // Dependency parent with dependency child Dependency::class => new Singleton(fn() => new Dependency()), ParentDependency::class => new Singleton( fn($container) => new ParentDependency($container->get(Dependency::class)) ), // Singleton passing factory as reference string ConcreteClass::class => new Singleton(ConcreteClassFactory::class) ]);
Peroxide\DependencyInjection\Invokables\Singleton
类作为包装器,用于指示我们的容器我们不希望每次检索时都创建此类的新实例。
Singleton
构造函数的第一个参数,只接受可调用类或闭包。
为什么我不能在容器上配置参数?
我们认为在依赖容器中存储配置值是不必要的。相反,每个服务都应该使用外部环境数据来配置。这样做可以将你项目的配置集中化。