clippy / container
受 Pimple 和 PHP-DI Invoker 启发的依赖注入容器
v1.4.2
2022-12-08 04:23 UTC
Requires
- php: >=7.2
- php-di/invoker: ~2.0
- pimple/pimple: ~3.0
- psr/container: ~1.1||~2.0
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']);