xp-forge / inject
XP 框架的依赖注入
v6.0.0
2024-03-24 11:29 UTC
Requires
- php: >=7.4.0
- xp-framework/core: ^12.0 | ^11.0 | ^10.0
- xp-framework/reflection: ^3.0 | ^2.0
Requires (Dev)
- xp-framework/test: ^2.0 | ^1.0
- dev-master
- v6.0.0
- v5.5.0
- v5.4.0
- v5.3.0
- v5.2.0
- v5.1.2
- v5.1.1
- v5.1.0
- v5.0.2
- v5.0.1
- v5.0.0
- v4.4.0
- v4.3.2
- v4.3.1
- v4.3.0
- v4.2.0
- v4.1.0
- v4.0.0
- v3.1.0
- v3.0.0
- v2.2.0
- v2.1.0
- v2.0.0
- v1.1.0
- v1.0.2
- v1.0.1
- v1.0.0
- v0.7.0
- v0.6.0
- v0.5.0
- v0.4.0
- dev-feature/implementations
- dev-feature/traits
- dev-refactor/drop-php5.5
- dev-feature/new-syntax
This package is auto-updated.
Last update: 2024-09-21 08:28:16 UTC
README
inject 包包含了 XP 框架的依赖注入 API。它的入口类是 "Injector"。
绑定
可以使用注入器的 bind()
方法将值绑定到注入器上。它接受要绑定的类型、可选名称和以下不同场景
- 绑定一个类:最典型的用法,将接口绑定到其具体实现。
- 绑定一个实例:通过将类型绑定到现有实例,可以创建一个 单例 模型。
- 绑定一个提供者:如果需要更复杂的代码来创建实例,可以绑定到提供者。
- 绑定一个命名查找:如果我们想控制类型的绑定查找,我们可以绑定到
Named
实例。
use inject\{Injector, Bindings}; use com\example\{Report, HtmlReport, Storage, InFileSystem}; // Manually $injector= new Injector(Bindings::using() ->typed(Report::class, HtmlReport::class) ->singleton(Storage::class, new InFileSystem('.')) ->named('title', 'Report title') ); // Reusable via Bindings instances class ApplicationDefaults extends Bindings { public function configure($injector) { $injector->bind(Report::class, HtmlReport::class); $injector->bind(Storage::class, new InFileSystem('.')); $injector->bind('string', 'Report title', 'title'); } } $injector= new Injector(new ApplicationDefaults());
实例创建
请注意:"injector.get() 是新的 'new'"。要创建对象和执行注入,请使用注入器的 get() 方法而不是使用 new
关键字或工厂。
use inject\Injector; $injector->bind(Report::class, HtmlReport::class); // Explicit binding: Lookup finds binding to HtmlReport, creates instance. $instance= $injector->get(Report::class); // Implicit binding: No previous binding, TextReport instantiable, thus created. $instance= $injector->get(TextReport::class);
通常不需要手动调用,而是使用注入
注入
通过查看类型的构造函数来执行注入。根据给定的类型提示传递绑定的值。
class ReportImpl implements Report { public function __construct(ReportWriter $writer) { ... } }
如果 PHP 类型系统不够简洁,可以通过使用参数属性来提供类型。如果绑定的值的名称与参数名称不同,可以提供名称参数。
use inject\Inject; class ReportImpl implements Report { public function __construct( ReportWriter $writer, Format $format, #[Inject(type: 'string[]', name: 'report-titles')] $titles ) { ... } }
当遇到所需的参数但没有为该参数绑定值时,会引发 inject.ProvisionException
。
class ReportWriter implements Writer { public function __construct(Storage $storage) { ... } } $injector= new Injector(); $report= $injector->get(ReportWriter::class); // *** Storage not bound
不支持方法和字段注入。
配置
如上所示,可以使用绑定而不是手动执行连接。您可能希望将应用程序的一些设置配置在外部,而不是硬编码。为此请使用 inject.ConfiguredBindings
类。
$injector= new Injector( new ApplicationDefaults(), new ConfiguredBindings(new Properties('etc/app.ini')) );
这些 INI 文件的语法很简单
web.session.Sessions=web.session.InFileSystem("/tmp") name="Application"
提供者
提供者允许实现延迟加载语义。绑定到注入器的每个类型也可以通过提供者检索。调用其 get() 方法将实例化它。
$provider= $injector->get('inject.Provider<com.example.writers.ReportWriter>'); // ...later on $instance= $provider->get();
命名查找
如果需要控制查找,我们可以绑定 Named
实例。
use inject\{Injector, Named, InstanceBinding}; use com\example\Value; $inject= new Injector(); $inject->bind(Value::class, new class() extends Named { public function provides($name) { return true; } public function binding($name) { return new InstanceBinding(new Value($name)); } }); $value= $inject->get(Value::class, 'default'); // new Value("default")