动态依赖注入管理器

v0.1.0 2014-01-08 20:34 UTC

This package is auto-updated.

Last update: 2024-08-25 20:11:07 UTC


README

Build Status Scrutinizer Quality Score Code Coverage

该库提供了一个用于动态处理依赖注入的类。

动态依赖注入意味着您不需要定义服务或定义哪些依赖需要注入。依赖项将根据构造函数参数动态创建。

这意味着您只需为要注入到类构造函数中的类添加类型提示即可。

安装

Composer

使用 composer 安装此库,请在您的 composer.json 中添加以下内容

{
    "require": {
        "pierredup/di": "*"
    }
}

确保您使用 composer 的自动加载器包含文件

require 'vendor/autoload.php';

下载文件

从存储库中下载 Di.phar 并将其保存到项目的路径中。

require 'path/to/Di.phar';

使用

获取带依赖项的类

namespace Foo {

    class Bar
    {
        public function __construct(Baz $baz)
        {
            // ...
        }
    }

    class Baz {

    }
}

$object = Di::get('Foo\Bar');

var_dump($object);

这将为 Foo\Bar 创建一个实例,并动态创建 Baz 类并将其注入到构造函数中。

获取新类的实例

默认情况下,每次调用 Di::get 时都会返回每个类的相同实例。如果您想返回类的新的实例,您需要将第二个参数传递给 get 方法

    $object = Di::get('Foo\Bar', Di::NEW_INSTANCE);

这将返回 Foo\Bar 类的新实例,但依赖项将始终返回相同的实例。

如果您要确保每个对象都返回新的实例,您需要传递 Di::DEEP 标志

    $object = Di::get('Foo\Bar', Di::DEEP);

这将返回 Foo\Bar 的新实例,以及每个依赖项的新实例。

参数

设置参数

如果您的构造函数中有无法用对象类型提示的值(例如数据库设置),您可以使用 map 方法设置这些参数的值

class Db
{
    public function __construct($host, $username, $password)
    {
        // ...
    }
}

Di::map(array(
    'host'      => 'localhost',
    'username'  => 'user',
    'host'      => 'password',
));

$object = Di::get('Db');

注意: 如果您未指定未具有类型提示的参数的值,则将传递 NULL 作为值。如果您为参数设置了默认值,则将使用该默认值。

懒加载参数

如果您想对参数进行懒加载(仅在需要时加载,例如从数据库或会话中获取值),您可以使用闭包或有效回调作为参数

Di::map(array(
    'parameter' => function() {
        return Di::get('Foo\Database')->getValueFromDb()
    }
));

// OR

Di::map(array(
    'parameter' => array($db, 'getValueFromDb')
));

函数或回调仅在需要参数时执行,然后将值缓存以供后续调用。

获取参数

要获取参数值,只需将 Di::PARAM 标志传递给 get 方法

Di::map(array(
    'host'      => 'localhost',
    'username'  => 'user',
    'host'      => 'password',
));

$host = Di::get('host', Di::PARAM); // return 'localhost'

覆盖类

您还可以使用 map 方法来覆盖类名。如果您想用自己的实现覆盖库的核心类,这很有用。请注意,您的类需要从您要覆盖的类扩展,否则您可能会遇到错误或意外的结果。

namespace Foo {
    class Bar
    {

    }
}

namespace Baz {
    use Foo\Bar;

    class FooBar extends Bar
    {

    }
}

Di::map(array(
    'Foo\Bar' => 'Baz\FooBar'
));

$object = Di::get('Foo\Bar'); // will return an instance of `Baz\FooBar`

TODO

  • 设置器注入 #1
  • 缓存类实例 #2
  • 定义服务 #3
  • 将接口映射到具体类 #4