corviz/di-container

一个简单而强大的自动装配容器

v1.0 2022-06-28 13:31 UTC

This package is auto-updated.

Last update: 2024-08-28 20:53:13 UTC


README

一个简单而强大的自动装配容器

安装

composer require corviz/di-container

用法

在使用容器+依赖注入时,您可能会遇到以下常见场景:

对于这些示例,我们将假设以下类

class A
{
    public funtion doSomething(){ /* ... */ }
    public function __construct() { echo "new instance of A"; }
}

class B
{
    public function __construct(A $a) { echo "new instance of B"; }
}

从容器中检索新实例

请注意,不需要之前的声明!

use Corviz\DI\Container;

$container = new Container();
$a = $container->get(A::class);

$a->doSomething(); //It works! :)

自动装配和参数类型

如果我们需要B的新实例怎么办?

$b = $container->get(B::class);

//Outputs:
//new instance of A
//new instance of B

因为我们声明了一个构造函数中的参数类型为"A",并且它是一个类,我们的容器将尝试通过反射自动创建一个新的实例。

如果我们需要接收原始类型作为参数,我们必须声明默认值,否则容器将抛出ContainerException,因为它无法猜测如何填充它。

手动设置

在某些特定情况下,您可能希望手动设置一些对象。为此,只需使用 'set' 方法即可。

//Whenever this interface is met, the container will declare a class instance instead:
$container->set(AInterface::class, A::class);

//Declaring a constructor. This function will be called whenever 'B' class is met.
//Note: a closure is REQUIRED, in this case
$container->set(B::class, function (){
    $param1 = new A();
    
    return new B($param);
});

//Defining an instance. Whenever this interface is met, the same object will be accessed
$container->set(AInterface::class, new A());

别名

如果我们想别名字符,我们只需要像通常一样在我们的容器中设置它

$container->set('s3', new S3Client(/* ... */));

//...

$s3 = $container->get('s3');

单例

当我们想要在整个执行期间访问相同的对象时,我们只需要使用 'setSingleton'。它接受与 'set' 相同的定义变体。换句话说,您可以使用类名、构造函数闭包或对象实例。

$container->setSingleton(Queue::class, function(){
    $queue = new Queue();
    
    //setup...
    
    return $queue;
});

$queue = $container->get(Queue::class);
$queue->add(/* ... */);
echo $queue->count(); //1

//Somewhere else:

$queue = $container->get(Queue::class);
$queue->add(/* ... */);
echo $queue->count(); //2

调用方法

让我们假设以下类

class Person
{
    public function sayHello(string $name, string $surname = '')
    {
        echo "Hello $name $surname!";
    }
    
    public function sendMailMessage(PHPMailer $mail)
    {
        //send routine...
    }
}

$person = new Person();

// Inform only required parameters
$container->invoke($person, 'sayHello', [
    'name' => 'John'
]); //Hello John !

// Inform required and optional parameters
$container->invoke($person, 'sayHello', [
    'name' => 'John',
    'surname' => 'Doe',
]); //Hello John Doe!

// Mailer class automatically bound (auto wire)
$container->invoke($person, 'sendMailMessage');