gspataro/dependencyinjection

一个依赖注入容器组件,用于处理您的应用程序的启动过程

1.0.0 2023-03-09 16:55 UTC

This package is auto-updated.

Last update: 2024-09-10 22:06:21 UTC


README

一个用于简化应用程序启动过程的依赖注入容器组件。

安装

需要 [PHP 8.0+](PHP: 发布)

要安装此包,您必须使用 Composer 引入它

composer require gspataro/dependencyinjection

快速入门

使用容器的最快方式是初始化它并提供您需要的所有服务

<?php

use GSpataro\DependencyInjection\Container;

$container = new Container();

/**
 * Register a new service
 * 
 * @param string   $tag                The name that will identify this service
 * @param callable $factory            The factory that will create the instance of the class
 * @param bool     $isSingleton = true If true, the service will be instanciated once the first time
 */

$container->add("example", function (Container $c, array $params) {
    return new stdClass();
});

/**
 * Get a service
 * Note: if the service is a singleton, the $params array will be used only the first time this method is called
 * 
 * @param string $tag        The identifier of the service
 * @param array $params = [] An array of arguments used by the factory to instanciate the class
 */

$container->get("example");

容器

Container 类是这个组件的核心。

服务依赖

当定义一个服务时,Container 类和参数数组被传递给工厂,以便可以访问类依赖项。

/**
 * Let's assume the class of this service will need the "example" class created in the quick start guide
 * and some other informations
 */

$container->add("second_example", function (Container $c, array $params) {
    return new stdClass($c->get("example"), $params['someinfo']);
});

变量

有时一些配置或其他变量需要在服务之间全局使用。在这种情况下,您可以为容器定义可访问的变量。

/**
 * Set a variable
 * 
 * @param string $key          The name of the variable
 * @param mixed  $value = null The value of the variable (if null, the method will retrieve the value instead of setting it)
 */

$container->variable("foo", "bar");

/**
 * Get a variable
 * 
 * Output: bar
 */

$container->variable("foo");

直接实例化

如果您需要实例化一个新类,但又不需要将其注册为服务,您可以直接实例化它。这不被推荐,但在某些情况下您仍然需要这样做。

/**
 * Directly instanciate a class
 * 
 * @param callable $factory  The factory that will instanciate the class
 * @param array $params = [] Arguments needed by the factory
 */

Container::instanciate(function (Container $c, array $params) {
    return new stdClass();
});

组件

组件是容器的一个另一个功能。问题是:如果您逐个定义服务,则在服务启动之前启动其依赖项的风险更高,并且您必须记住首先启动了什么。

为了简化这个过程,组件是按您指定的顺序启动的服务的“存档”。

定义组件

<?php

use GSpataro\DependencyInjection\Component;
use GSpataro\DependencyInjection\Container;

/**
 * A component must extend the Component abstract class
 */

final class MyComponent extends Component
{
    /**
     * Register the services that you need
     */

    public function register(): void
    {
        $this->container->add("myservice", function (Container $c, array $params) {
            return new stdClass();
        });
    }

    /**
     * If your services need to be booted with the application, call them inside this method
     * Here you can handle everything your service needs in order to boot
     */

    public function boot(): void
    {
        $this->container->get("myservice");
    }
}

启动组件

要启动您的组件,您需要将其注册到容器中,然后调用启动方法。

/**
 * Register components
 */

$container->loadComponents([
    MyComponent::class
]);

/**
 * Boot components
 */

$container->boot();

假设您有两个组件:ComponentA 和 ComponentB。如果 ComponentA 依赖于由 ComponentB 提供的一些服务,您可以在 loadComponents 方法中更改它们的顺序。

$container->loadComponents([
    ComponentB::class,
    ComponentA::class
]);