hughnoble/injector

一个易于配置和灵活的PSR-11兼容的IoC容器,适用于PHP

1.0.1 2019-05-17 12:19 UTC

This package is not auto-updated.

Last update: 2024-09-24 17:36:22 UTC


README

Build Status

Injector IoC

一个易于配置和灵活的PSR-11兼容的IoC容器,适用于PHP。

基本用法

最简单的用法如下。

$map = new \Injector\Binding\BindingMap;
$container = \Injector\ContainerFactory::makeContainer($map);

// Any type hinted constructor parameters will be auto-wired.
$class = $container->get(MyClass::class);

自动绑定

默认情况下,容器将自动尝试解析它能够解析的任何依赖项,而无需将它们绑定。

class UserRepository
{
    public function __construct(EntityManager $user)
    ...
}

如果EntityManager类可实例化(不是一个接口或抽象类,并且没有无法解决的依赖项)则容器将使用以下代码解析它。

$userRepository = $container->get(UserRepository::class);

然而,如果依赖项是一个接口或抽象类,则需要绑定。有几种不同的方法可以做到这一点。

自动绑定的绑定

最常见的绑定形式是将它们绑定到一个具体实现上,以便它们可以被自动绑定。

$map->add(
    MyInterface::class,
    new Injector\Dependency\AutoWireDependency(MyConcrete::class)
);

闭包绑定

$map->add(
    MyInterface::class,
    new Injector\Dependency\ClosureDependency(function($container){
        return new MyConcrete(
            $container->get(ChildInterface::class),
            'something-that-cannot-be-resolved'
        );
    })
);

在这个例子中,闭包将在每次请求这个依赖项时运行。这意味着如果两个类在同一个进程内需要它,它们都将得到新的实例。

单例绑定

$childDependency = new Injector\Dependency\ClosureDependency(function($container){
    return new MyConcrete(
        $container->get(ChildInterface::class),
        'something-that-cannot-be-resolved'
    );
});

$map->add(
    MyInterface::class,
    new Injector\Dependency\SingletonBinding($childDependency)
);

在这种情况下,$childDependency内的闭包将在第一次请求时运行并缓存。后续的调用将导致返回相同的实例。

单例的子依赖项也可以是自动绑定的。这很有用,当你始终需要相同的实例时,并不限于接口绑定。

$childDependency = new Injector\Dependency\AutoWireDependency(MyClass::class);

$map->add(
    new Injector\Dependency\SingletonDependency(MyClass::class, $childDependency)
);

通过将类绑定为自己作为单例,可以确保始终返回相同的实例。

注入容器

以下保留的绑定可以用来将容器作为依赖项访问。

Injector\ContainerPsr\Container\ContainerInterface 将始终解析为容器的实例。

Injector\Binding\BindingMapInterface 将始终解析为容器正在使用的绑定映射。

这很有用,当你可能希望通过提供者进行编程式绑定时。

class UserServiceProvider
{
    private $bindingMap;

    public function __construct(\Injector\Binding\BindingMapInterface $bindingMap)
    {
        $this->bindingMap = $bindingMap;
    }

    public function bindDependencies()
    {
        $this->bindingMap->add(
            UserRepositoryInterface::class,
            new \Injector\Binding\AutoWireBinding(UserRepository::class)
        );
    }
}