ivanvoitovych / dot-di
PHP 的依赖注入(DI)和服务提供者。灵感来源于 .NET DI。
v1.1.3
2024-04-21 13:42 UTC
README
依赖注入和服务提供者,用于 PHP。灵感来源于 .NET DI。
使用方法
composer require ivanvoitovych/dot-di
require __DIR__ . '/../vendor/autoload.php'; use DotDi\DependencyInjection\ServiceProvider; use DotDi\DependencyInjection\ServiceProviderHelper; $services = new ServiceProvider(); // register a singleton $services->addSingleton(FooService::class); // register a transient $services->addTransient(BarService::class); // register scoped using interface as a type $services->addScoped(ITaxService::class, TaxService::class); $services->addScoped(GenericService::class); $services->addScoped(UserService::class); // factory $serviceProvider->addSingleton( IRedisConnector::class, function (Config $config) { // params are autoinjected return new RedisConnector($config->values['redisDbIndex']); } ); // to auto register everything in the folder (as Scoped, for ex.: controllers) ServiceProviderHelper::discover($services, ['path/to/your/files']);
使用泛型
class GenericService { public function __construct(private string $type, private ?string $dbMap = null, ?int $dbIndex = null) { } } ... // injecting generic type using Inject attribute class TestService { /** * * @param GenericService<UserEntity, UserEntityDbMap> $usersRepository * @return void */ public function __construct( #[Inject([ 'type' => 'UserEntity', 'dbMap' => 'UserEntityDbMap' ])] public GenericService $usersRepository ) { } } // extending generic class #[Inject([ 'type' => 'UserEntity', 'dbMap' => 'UserEntityDbMap' ])] class UserService extends GenericService { }
使用作用域
// creating a scope $scope = $services->createScope(); // getting a service $scope->serviceProvider->get(FooService::class); $scope->serviceProvider->get(ITaxService::class); // setting up a service for current scope only $requestScope->serviceProvider->set(HttpContext::class, new HttpContext()); // dispose at the end $scope->dispose();
适用于 swoole 或 ReactPHP
dot-di 非常高效且节省内存 - 没有内存泄漏。
与 IDisposable 一起使用来自动释放资源
<?php namespace Application\Swoole\Connectors; use DotDi\Interfaces\IDisposable; use Redis; use Swoole\Database\RedisPool; class SwooleRedisConnector implements IDisposable { private Redis $redis; public function __construct(private RedisPool $pool) { } /** * * @return Redis */ function get() { if (!isset($this->redis)) { $this->redis = $this->pool->get(); } return $this->redis; } // this will be called automatically function dispose() { if (isset($this->redis)) { $this->pool->put($this->redis); unset($this->redis); } } }
// swoole app example ... function handle(HttpContext $httpContext) { // create scope $scope = $this->serviceProvider->createScope(); try { // create request and http context $scope->serviceProvider->set(HttpRequest::class, $httpContext->request); $scope->serviceProvider->set(HttpResponse::class, $httpContext->response); $scope->serviceProvider->set(HttpContext::class, $httpContext); $requestDelegate = new RequestDelegate($this, $scope); $scope->serviceProvider->set(RequestDelegate::class, $requestDelegate); // run middleware(s) $requestDelegate(); // end response $httpContext->response->end(); } finally { // dispose the scope $scope->dispose(); } }
许可证
MIT 许可证
版权所有 (c) 2022 年至今 Ivan Voitovych
有关许可证文本,请参阅 LICENSE
法律
通过提交拉取请求,您放弃对 Viewi 项目的任何权利或索赔,并将这些更改的版权转让给 Ivan Voitovych。
如果您不能或不想转让这些权利(您的雇主的工作合同可能不允许这样做),则不应提交 PR。请提出一个问题,其他人可以完成这项工作。
这是说“如果您向我们提交 PR,那么代码就归我们所有”的法律方式。99.9% 的情况下,这就是您的意图;我们希望这不会让您害怕贡献。