2

我正在努力让依赖注入以我期望的方式工作 -

我正在尝试注入一个类 Api,它需要知道为特定用户连接到哪个服务器。这意味着在配置文件中覆盖构造函数属性是没有用的,因为每个用户可能需要连接到不同的服务器。

class MyController {
    private $api;

    public function __construct(Api $api) {
        $this->api = $api;
    }
}

class Api {
     private $userServerIp;

     public function __construct($serverip) {
         $this->userServerIp = $serverip;
     }
}

如何使用正确的参数注入此类?是否可以以某种方式覆盖定义?有没有办法通过带参数调用容器来获取类?

为了(希望)澄清 - 我试图调用容器来实例化一个对象,同时将原本在定义中的参数传递给它。

4

2 回答 2

1

由于 IP 取决于用户,因此您可能有一些执行 user=>serverIP 映射的逻辑。它可能是从 db 或简单的基于 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);
    }
}

Api现在,您可以注入而不是注入您的控制器ApiFactory(假设您的控制器知道它需要 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();
    }
}
于 2016-03-28T03:50:02.233 回答
1

我不确定我是否完全理解您的问题,但您可以Api像这样配置您的课程:

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');
    },
];
于 2016-03-26T18:57:49.247 回答