greg-md/php-dependency-injection

PHP 的依赖注入技术。

dev-master 2019-07-23 22:13 UTC

This package is auto-updated.

Last update: 2024-09-24 09:36:43 UTC


README

StyleCI Build Status Total Downloads Latest Stable Version Latest Unstable Version License

依赖注入提供了一种轻量级但强大的 IoC 容器,允许您标准化和集中管理应用程序中对象的构建方式。

目录

要求

  • PHP 版本 ^7.1

安装

composer require greg-md/php-dependency-injection

工作原理

要开始使用 依赖注入 技术,您只需要实例化一个 IoC 容器并将对象注入其中。

$ioc = new \Greg\DependencyInjection\IoCContainer();

注入

$ioc->inject('foo', Foo::class);

$ioc->inject('bar', new Bar());

您还可以使用更优雅的方式注入,使用对象名称作为抽象。

$ioc->register(new Foo());

上一个示例等同于以下内容

$ioc->inject(Foo::class, new Foo());

自定义对象的实例化方式。

$ioc->inject('redis.client', function() {
    $redis = new \Redis();

    $redis->connect();

    return $redis;
});

获取

下一个示例将在对象未注入 IoC 容器时返回 null。

$foo = $ioc->get('foo');

期望

下一个示例将在参数未注入 IoC 容器时抛出异常。

$foo = $ioc->expect('foo');

加载

在实际应用程序中,为了充分利用依赖注入技术的优势,您可能希望从 IoC 容器中实例化具有依赖关系的对象,而不必手动定义它们。这样做最好的方法是注入具有其名称或其策略名称的抽象对象。

假设我们有一个 Foo 类,它需要一个 BarStrategy 类。

class Foo
{
    private $bar;
    
    public function __construct(BarStrategy $bar)
    {
        $this->bar = $bar;
    }
}

我们做的就是将 BarStrategy 注入到 IoC 容器中,并从它加载 Foo 类。

BarStrategy 是一个 接口,所以我们不会破坏 SOLID 原则。

$ioc->inject(BarStrategy::class, function() {
    return new Bar();
});

$foo = $ioc->load(Foo::class);

有时您可能希望在从 IoC 容器加载类时重新定义一个或多个类的依赖关系。

class Foo
{
    private $bar;
    
    private $baz;
    
    public function __construct(BarStrategy $bar, BazStrategy $bar)
    {
        $this->bar = $bar;
        
        $this->baz = $baz;
    }
}
$ioc->inject(BarStrategy::class, function() {
    return new Bar();
});

$ioc->inject(BazStrategy::class, function() {
    return new Baz();
});

您可以通过在 load 方法中在类名之后定义这些依赖关系来轻松地做到这一点。

$customBaz = new CustomBaz();

$foo = $ioc->load(Foo::class, $customBaz);

上一个示例将从 IoC 容器实例化 BarStrategy(即 Bar 类),对于 BazStrategy,它将在 load 方法中设置 CustomBaz

您还可以使用数组作为参数加载。

$ioc->loadArgs(Foo::class, [new CustomBaz()]);

调用

您可以像加载类一样,使用注入到 Ioc 容器中的参数调用可调用对象。

$ioc->call(function(int $foo, Bar $bar) {
    // $bar will be injected from the Ioc Container.
}, 10);

您也可以使用数组作为参数调用可调用对象。

$ioc->callArgs([$someObj, 'someMethod'], ...$arguments);

自动加载

您可以通过定义前缀/后缀作为抽象来自动加载一些类。

$ioc->addPrefixes('Foo\\');

$ioc->addSuffixes('Controller');

$controller = $ioc->get(\Foo\BarController::class);

许可

MIT © Grigorii Duca

长引用

I fear not the man who has practiced 10,000 programming languages once, but I fear the man who has practiced one programming language 10,000 times. © #horrorsquad