2016-03-26 33 views
1

我努力讓依賴注入來工作,我所期望的方式構造 -注射參數與PHP-DI

我想注入類的API,它需要知道連接到了哪個服務器特定用戶。這意味着在配置文件中覆蓋構造函數屬性是無用的,因爲每個用戶可能需要連接到不同的服務器。

class MyController { 
    private $api; 

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

class Api { 
    private $userServerIp; 

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

如何爲這個類注入正確的參數?是否有可能以某種方式覆蓋定義?有什麼方法通過調用具有參數的容器來獲取類?

(希望)澄清 - 我試圖調用容器來實例化一個對象,同時傳遞給它的參數,否則將在一個定義。

回答

1

由於IP取決於你ser你可能有一些邏輯,用戶=> 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); 
    } 
} 

現在不是注入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(); 
    } 
} 
-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'); 
    }, 
]; 
+0

嗨, - 是啊所以在這個定義中,所有的Api對象將有IP'127.0.0.1' - 我怎樣才能調用容器,因此它實例化一個不同的IP的Api? – PointToPoint

+0

@PointToPoint請參閱編輯。還請閱讀文檔,嘗試一些內容並解釋您嘗試的內容,最好了解您被阻止的位置。 –