ice-cream di (依赖注入) 是我对 DI 的个人理解,使其简单易用。

1.2.1 2018-03-16 21:16 UTC

This package is not auto-updated.

Last update: 2024-09-14 19:04:15 UTC


README

Build Status Packagist Maintenance Made With Love

  • 需要 PHP 7.2.x
  • 独立

我想找到一种简单有效的方法来复制 pimple 并在最低层次上创建 DI。

核心概念很简单,你有一个容器,可以向其中添加项目并通过 ArrayAccess 接口获取。

我们还允许你创建工厂,这使得你每次都能返回对象的新实例,而不是每次都返回相同的对象。

文档

您可以在这里查看此包的文档

理念

Ice Cream 并非旨在成为 OSS 中的下一个大事件。它本质上是对 Pimple 的模仿。

我想构建一个简单的 DI 容器,我可以在自己的项目中使用它来尝试更深入地理解 DI 的基本概念。

示例

以下是如何使用容器的非常基本的示例。

use IceCreamDI\Container;

$container = new Container();

$container['service'] = function($c) {
  return new Service();
}

$container['services'] // Returns instance of Service class.

注意!!

我们将容器实例传递给所有的闭包,这与 pimple 完全一样。即使是在扩展已经注册的服务提供者时,你也可以确信新的扩展也将有容器对象。

更简单

$container = new Container([
  'app.service' => function ($c) {
    return new Service();
  },
]);

注意!

如果你在容器中有一个具有相同名称的项,并且你将另一个对象放入具有相同名称的项中,你会破坏你的容器。确保你的名称是唯一的。

注意!

你无法在调用容器对象之后操纵它,例如

$container = new Container();
$container['service'] = function ($c) { return new Service(); };

$service = $container['service'];

$container->extend('service', function($service){ $service->someMethodCall(); });

上面的代码将产生错误,因为当你从服务容器中“构建”项时,我们会将其锁定。

如果你想在容器中扩展已注册的项,我们可以这样做

use IceCreamDI\Container;

$container = Container();

$container['service'] = function($c) {
  return new Service();
}

$container->extend('service', function($service){
  $service-> ....

  ....

  return $service;
});

这允许你轻松注册并操作容器中的项。

如果你只想获取闭包,你可以调用原始方法

use IceCreamDI\Container;

$container = Container();

$container['service'] = function($c) {
  return new Service();
}

$container->raw('service'); // => closure instance.

当你调用工厂方法时,你将 始终 获取已注册对象的新的实例。例如

use IceCreamDI\Container;

$container = Container();

$container['service'] = $container->factory(function($c) {
  return new $service();
});

$container['service']; // => Will be a new instance every time.

而使用常规 $container['service'] 你将始终获取相同的对象。

如果你的工厂有依赖项怎么办?例如,假设你有一个类,每次调用它时,你都需要将依赖项注入到类中。你可以使用 resolveFactory 方法

use IceCreamDI\Container;

$container = Container();

$container['service_deps'] = [
  'dep1' => ...,
  ...
];

// Notice how you even have access to the containe object $c.
$container['service'] = $container->factory(function($dep1, $dep2, ..., $c) {
  return new $service($dep1, $dep2, ...);
});

$container->resolveFactory('service', 'service_deps'); // Gives you a new service instance with deps passed in.

如上所示,我们注入了依赖项。我们甚至添加了一个附加的依赖项,即 $c 容器对象依赖项,这样将被解析的注册工厂就有容器的一个实例。

我们也可以调用容器对象的方法

use IceCreamDI\Container;

$container = Container();

$container['service'] = function() { return new Service(); };

$container->call('service', 'process'); // Same as doing: $container['service']->process();