clippy/container

受 Pimple 和 PHP-DI Invoker 启发的依赖注入容器

v1.4.2 2022-12-08 04:23 UTC

This package is not auto-updated.

Last update: 2024-09-12 12:11:05 UTC


README

这是基于 pimple 的衍生版本,有一些显著的变化。

函数参数注入

在标准 Pimple 中,服务工厂都接收 Container $c 作为输入,例如

$c['descendent'] = function($c) {
  return $c['parent']->generateDescendent()->withWhizBang();
};

在 Clippy 的容器中

$c['descendent'] = function(MyParent $parent) {
  return $parent->generateDescendent()->withWhizBang();
};

这使得服务的消费者可以(渐进式地)使用类型提示。

服务方法

"服务方法"是一个既支持服务注入也支持运行时数据传递的函数。例如

$c['getPassword()'] = function ($domain, SymfonyStyle $io) {
  if (getenv('PASSWORD')) return getenv('PASSWORD');
  return $io->askHidden("What is the password for <comment>$domain</comment>?");
}
$c['app']->main('', function($getPassword) {
  $pass = $getPassword('example.com');
});

getPassword 的第一个参数在运行时给出($getPassword('example.com'));第二个参数($io)会自动注入。

服务方法通过在声明中包含 () 来表示。比较

// Standard service
$c['foo'] = function($injectedService, ...) { ... }

// Service method
$c['foo()'] = function($inputtedData, ... , $injectedService, ...)  { ... }
};

自动注入对象/匿名服务类

以下允许使用注入与临时服务类。

$c['basicService'] = 'something';
$c['newService'] = $c->autowiredObject(new class() {

  protected $basicService;

  public function double() {
    return $this->basicService . $this->basicService;
  }

});

属性(例如 $basicService)将预填充相应的服务。

在默认的 strict 模式下,不匹配的属性将产生异常。这可以被禁用,例如

$c['newService'] = $c->autowiredObject(['strict' => FALSE], new class() { ..});

类似地,你可以定义一个常规服务函数,并将自动注入作为逻辑的一部分使用,例如

$c['basicService'] = 'something';
$c['newService'] = function() use ($c) {
  return $c->autowire(new MyClass());
};

符号

在标准 Pimple 中,你可以通过使用包装方法来定义回调的替代处理。Clippy 支持包装方法以及符号表示法。

// Run a function every time one reads `$c['theJoneses]`, with mix of inputs and services
$c['getPassword'] = $c->method(function ($domain, SymfonyStyle $io) { ... });
$c['getPassword()'] = function ($domain, SymfonyStyle $io) { ... };
$c['getPassword']('localhost');
$c['getPassword']('example.com');

// Create a new instance every time one reads `$c['theJonses']`:
$c['theJoneses'] = $c->factory(function() { return new CoolThing(microtime(1)); });
$c['theJoneses++'] = function() { return new CoolThing(microtime(1)); };
print_r($c['theJoneses']);
print_r($c['theJoneses']);