ghostwriter / container
提供可扩展的依赖注入服务容器,用于自动对象组合、拦截和生命周期管理。
4.0.2
2024-07-13 14:57 UTC
Requires
- php: >=8.3
Requires (Dev)
- ghostwriter/coding-standard: dev-main
- 5.0.x-dev
- 4.1.x-dev
- 4.0.x-dev
- 4.0.2
- 4.0.1
- 4.0.0
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.0.1
- 2.0.0
- 1.6.0
- 1.5.0
- 1.4.0
- 1.3.0
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.0
- 0.7.0
- 0.6.0
- 0.5.0
- 0.4.0
- 0.3.2
- 0.3.1
- 0.3.0
- 0.2.2
- 0.2.1
- 0.2.0
- 0.1.1
- 0.1.0
- dev-chore/merge-up/merge-4.1.x-into-5.0.x-da1656b
- dev-chore/merge-up/merge-4.0.x-into-4.1.x-da1656b
- dev-chore/phpunit/configuration-2ae768b
- dev-main
This package is auto-updated.
Last update: 2024-09-02 02:03:55 UTC
README
提供可扩展的依赖注入服务容器,用于自动对象组合、拦截和生命周期管理。
安装
您可以通过 composer 安装此包。
composer require ghostwriter/container
用法
简单用法
在给定的容器中注册服务。
final readonly class Service { public function __construct( private Dependency $dependency ) {} public function dependency():Dependency { return $this->dependency; } } $container = Container::getInstance(); $service = $container->get(Service::class); assert($service instanceof Service); // true assert($service->dependency() instanceof Dependency); // true
属性
使用属性注册服务。
#[Inject]
使用属性在容器中注册服务。
use Ghostwriter\Container\Attribute\Inject; final readonly class Service { public function __construct( #[Inject(Dependency::class)] private DependencyInterface $dependency ) {} public function dependency():Dependency { return $this->dependency; } } // the above is equivalent to the following // $container->alias(Dependency::class, DependencyInterface::class); final readonly class Service { public function __construct( #[Inject(Dependency::class, Service::class)] private DependencyInterface $dependency ) {} public function dependency():Dependency { return $this->dependency; } } // the above is equivalent to the following // $container->bind(Service::class, DependencyInterface::class, Dependency::class);
使用属性在容器中注册服务工厂。
#[Factory]
use Ghostwriter\Container\Attribute\Factory; #[Factory(ServiceFactory::class)] final readonly class Service { public function __construct( #[Factory(DependencyFactory::class)] private Dependency $dependency ) {} public function dependency():Dependency { return $this->dependency; } } // the above is equivalent to the following // $container->factory(Dependency::class, DependencyFactory::class); // $container->factory(Service::class, ServiceFactory::class);
#[扩展]
使用属性在容器中注册服务扩展。
use Ghostwriter\Container\Attribute\Extension; #[Extension(ServiceExtension::class)] final readonly class Service { public function __construct( #[Extension(DependencyExtension::class)] private Dependency $dependency ) {} public function dependency():Dependency { return $this->dependency; } } // the above is equivalent to the following // $container->extend(Service::class, ServiceExtension::class); // $container->extend(Dependency::class, DependencyExtension::class);
服务提供者
在容器中注册服务提供者。
interface TaskInterface {} final readonly class Task implements TaskInterface {} final class Tasks { private array $tasks = []; public function addTask(TaskInterface $task) { $this->tasks[] = $task; } } final readonly class TasksServiceProvider implements ServiceProviderInterface { public function __invoke(ContainerInterface $container) { $container->alias(TaskInterface::class, Task::class); $container->set(Tasks::class, static function (Container $container) { /** @var Tasks $tasks */ $tasks = $container->build(Tasks::class); foreach ($container->tagged(Task::class) as $service) { $tasks->addTask($service); } return $tasks; }, [Tasks::class, 'tasks']); } } $container->provide(TasksServiceProvider::class); $service = $container->get(TaskInterface::class); assert($service instanceof Task); // true
上下文绑定
在容器中注册上下文绑定。
interface ClientInterface { } final readonly class RestClient implements ClientInterface { } final readonly class GraphQLClient implements ClientInterface { } final readonly class GitHub { public function __construct( private ClientInterface $client ) { } public function getClient(): ClientInterface { return $this->client; } } // When GitHub::class asks for ClientInterface::class, it would receive an instance of GraphQLClient::class. $container->bind(GitHub::class, ClientInterface::class, GraphQLClient::class); // When any other service asks for ClientInterface::class, it would receive an instance of RestClient::class. $container->alias(ClientInterface::class, RestClient::class);
服务扩展
在容器中注册服务扩展。
/** * @implements ExtensionInterface<GitHubClient> */ final readonly class GitHubExtension implements ExtensionInterface { /** * @param GitHubClient $service * @return GitHubClient */ public function __invoke(ContainerInterface $container, object $service): object { $service->setEnterpriseUrl( $container->get(GitHubClient::GITHUB_HOST) ); return $service; } } $container->alias(GitHubClientInterface::class, GitHubClient::class); $container->extend(GitHubClientInterface::class, $container->get(GitHubExtention::class));
服务工厂
在容器中注册服务工厂。
final readonly class Dependency {} final readonly class Service { public function __construct( private Dependency $dependency ){} public function dependency():Dependency { return $this->dependency; } } final readonly class ServiceFactory { public function __invoke(Container $container): Service { return new Service($container->get(Dependency::class)); } } $container = Container::getInstance(); $container->factory(Service::class, ServiceFactory::class); $service = $container->get(Service::class); assert($service instanceof Service); // true assert($service->dependency() instanceof Dependency); // true
测试
composer test
变更日志
请参阅 CHANGELOG.md 了解最近更改的详细信息。
安全
如果您发现任何安全相关的问题,请发送电子邮件至 nathanael.esayeas@protonmail.com
,而不是使用问题跟踪器。
赞助商
致谢
许可
BSD-3-Clause 许可。请参阅 许可文件 了解更多信息。