使用 PHP-DI 将参数注入构造函数
Injecting parameters into constructor with PHP-DI
我正在努力让依赖注入以我期望的方式工作 -
我正在尝试注入 class、Api,它需要知道为特定用户连接到哪个服务器。这意味着覆盖配置文件中的构造函数属性是无用的,因为每个用户可能需要连接到不同的服务器。
class MyController {
private $api;
public function __construct(Api $api) {
$this->api = $api;
}
}
class Api {
private $userServerIp;
public function __construct($serverip) {
$this->userServerIp = $serverip;
}
}
如何使用正确的参数注入此 class?是否有可能以某种方式覆盖定义?有没有办法通过调用带有参数的容器来获取 class?
为了(希望)澄清 - 我正在尝试调用容器来实例化一个对象,同时向它传递原本会在定义中的参数。
我不确定我是否完全理解你的问题,但你可以像这样配置你的 Api
class:
return [
'Foo' => function () {
return new Api('127.0.0.1');
},
];
查看文档以获取更多示例或详细信息:http://php-di.org/doc/php-definitions.html
编辑:
return [
'foo1' => function () {
return new Api('127.0.0.1');
},
'foo2' => function () {
return new Api('127.0.0.2');
},
];
由于 IP 取决于用户,您可能有一些逻辑来执行 user=>serverIP 映射。它可能是从数据库读取或简单的基于 id 的分片,或其他任何东西。使用该逻辑,您可以构建 ApiFactory
为特定用户创建 Api
的服务:
class ApiFactory {
private function getIp(User $user) {
// simple sharding between 2 servers based on user id
// in a real app this logic is probably more complex - so you will extract it into a separate class
$ips = ['api1.example.com', 'api2.example.com'];
$i = $user->id % 2;
return $ips[$i];
}
public function createForUser(User $user) {
return new Api($this->getIp($user);
}
}
现在您可以注入 ApiFactory
而不是将 Api
注入您的控制器(假设您的控制器知道它需要 Api 实例的用户)
class MyController {
private $apiFactory;
public function __construct(ApiFactory $apiFactory) {
$this->apiFactory = $apiFactory;
}
public function someAction() {
$currentUser = ... // somehow get the user - might be provided by your framework, or might be injected as well
$api = $this->apiFactory->createForUser($currentUser);
$api->makeSomeCall();
}
}
我正在努力让依赖注入以我期望的方式工作 -
我正在尝试注入 class、Api,它需要知道为特定用户连接到哪个服务器。这意味着覆盖配置文件中的构造函数属性是无用的,因为每个用户可能需要连接到不同的服务器。
class MyController {
private $api;
public function __construct(Api $api) {
$this->api = $api;
}
}
class Api {
private $userServerIp;
public function __construct($serverip) {
$this->userServerIp = $serverip;
}
}
如何使用正确的参数注入此 class?是否有可能以某种方式覆盖定义?有没有办法通过调用带有参数的容器来获取 class?
为了(希望)澄清 - 我正在尝试调用容器来实例化一个对象,同时向它传递原本会在定义中的参数。
我不确定我是否完全理解你的问题,但你可以像这样配置你的 Api
class:
return [
'Foo' => function () {
return new Api('127.0.0.1');
},
];
查看文档以获取更多示例或详细信息:http://php-di.org/doc/php-definitions.html
编辑:
return [
'foo1' => function () {
return new Api('127.0.0.1');
},
'foo2' => function () {
return new Api('127.0.0.2');
},
];
由于 IP 取决于用户,您可能有一些逻辑来执行 user=>serverIP 映射。它可能是从数据库读取或简单的基于 id 的分片,或其他任何东西。使用该逻辑,您可以构建 ApiFactory
为特定用户创建 Api
的服务:
class ApiFactory {
private function getIp(User $user) {
// simple sharding between 2 servers based on user id
// in a real app this logic is probably more complex - so you will extract it into a separate class
$ips = ['api1.example.com', 'api2.example.com'];
$i = $user->id % 2;
return $ips[$i];
}
public function createForUser(User $user) {
return new Api($this->getIp($user);
}
}
现在您可以注入 ApiFactory
而不是将 Api
注入您的控制器(假设您的控制器知道它需要 Api 实例的用户)
class MyController {
private $apiFactory;
public function __construct(ApiFactory $apiFactory) {
$this->apiFactory = $apiFactory;
}
public function someAction() {
$currentUser = ... // somehow get the user - might be provided by your framework, or might be injected as well
$api = $this->apiFactory->createForUser($currentUser);
$api->makeSomeCall();
}
}