在開發一個大型php項目時,我遇到了一個棘手的問題:如何有效地管理服務依賴和生命周期。隨著項目的擴展,服務之間的依賴關系變得越來越復雜,手動管理這些依賴不僅耗時,而且容易出錯。我嘗試了幾種方法,但都沒有找到一個既靈活又高效的解決方案。最終,我通過使用ghostwriter/container庫成功解決了這個問題。
使用composer安裝ghostwriter/container非常簡單:
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
使用屬性注解
你還可以使用屬性注解來注冊服務,這使得代碼更加清晰和易于維護:
立即學習“PHP免費學習筆記(深入)”;
#[Inject]
use GhostwriterContainerAttributeInject; final readonly class Service { public function __invoke( #[Inject(Dependency::class)] DependencyInterface $dependency ): Dependency { return $this->dependency; } }
#[Factory]
use GhostwriterContainerAttributeFactory; #[Factory(ServiceFactory::class)] final readonly class Service { public function __construct( private Dependency $dependency ) {} public function dependency(): Dependency { return $this->dependency; } }
#[Extension]
use GhostwriterContainerAttributeExtension; #[Extension(ServiceExtension::class)] final readonly class Service { public function __construct( private Dependency $dependency ) {} public function dependency(): Dependency { return $this->dependency; } }
#[Provider]
use GhostwriterContainerAttributeProvider; #[Provider(ServiceProvider::class)] final readonly class Service { public function __construct( private DependencyInterface $dependency ) {} public function dependency(): DependencyInterface { return $this->dependency; } }
服務提供者
通過服務提供者,你可以更靈活地管理服務:
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(Task::class, TaskInterface::class); // "set" the service instance $container->set(FirstTask::class, new FirstTask(), [Task::class]); // "define" the service builder $container->define(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(GitHubExtension::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
使用ghostwriter/container庫,我能夠更加靈活和高效地管理服務依賴和生命周期。它不僅簡化了代碼,還提高了項目的可維護性和可擴展性。如果你在處理PHP項目中的依賴注入和服務管理問題,強烈推薦你嘗試這個庫。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END
喜歡就支持一下吧
相關推薦