![](/img/trans.png)
[英]Symfony2 Service Container - Passing ordinary arguments to service constructor
[英]Passing out of scope data to a service container
我希望創建一個SomeService
的新實例,該實例必須注入一些在 Pimple 中定義服務時未知的數據。 以下在技術上有效,但肯定不是這樣做的正確方法。 這應該如何實現?
<?php
use Pimple\Container;
class SomeService
{
private $theNewData;
public function __construct(MyPdo $pdo, array $theNewData){
$this->theNewData=$theNewData;
}
public function getJsonString():string{
return json_encode($this->theNewData);
}
}
class MyPdo{}
function getServiceSometimeInTheFuture(Container $container):SomeService {
$someFutureData= ['a'=>1,'b'=>2,'c'=>3,];
/*
How do I inject this content into SomeService other than using Pimple as a temporary transport?
*/
$container['temp']=$someFutureData;
$newInstance=$container['someService'];
unset($container['temp']);
return $newInstance;
}
require '../vendor/autoload.php';
$container=new Container();
$container['myPdo'] = function ($c) {
return new MyPdo();
};
$container['someService'] = $container->factory(function ($c) {
return new SomeService($c['myPdo'], $c['temp']);
});
$service = getServiceSometimeInTheFuture($container);
echo($service->getJsonString());
除了使用 Pimple 作為臨時傳輸之外,如何將此內容注入 SomeService?
我覺得這個問題的根本原因是future data
顧名思義就是數據,隨着時間的推移會發生多次變化,所以不應該在服務定義的時候傳遞給服務,而是每次服務中的使用者方法(此處為getJsonString
)需要該數據的時間。
...在定義服務時不知道
數據是未知的,但是數據的來源呢? 你能不能寫一個新的服務來充當數據提供者,這樣原來的服務可以在未來需要的時候獲取需要的數據?
我可以提出兩種解決方案。
(我故意從任何地方刪除 MyPdo 因為它根本沒有使用,即使在構造函數中也是如此)
如果您確實需要在創建時將數據傳遞給服務:
<?php
require __DIR__ . '/../vendor/autoload.php';
use Pimple\Container;
class SomeService
{
private $theNewData;
public function __construct(array $theNewData){
$this->theNewData=$theNewData;
}
public function getJsonString():string{
return json_encode($this->theNewData);
}
}
$container=new Container();
// Use pimple factory method to create new service instance, instead of creatng a custom function
$container['getServiceSometimeInTheFuture'] = $container->factory(function (Container $c):SomeService {
return new SomeService($c['futureData']);
});
// `futureData` returns new data every time
$container['futureData'] = $container->factory(function(){
return ['a' => rand(1, 10), 'b' => rand(1, 10), 'c' => rand(1, 10), ];
});
$service1 = $container['getServiceSometimeInTheFuture'];
$service2 = $container['getServiceSometimeInTheFuture'];
// Demonstrate how two different instances have different, persistent data
echo("\nservice 1:" . $service1->getJsonString());
echo("\nservice 2:" . $service2->getJsonString());
echo("\nservice 1:" . $service1->getJsonString());
echo("\nservice 2:" . $service2->getJsonString());
如果您可以推遲在將來需要該數據時向該服務提供數據:
<?php
require __DIR__ . '/../vendor/autoload.php';
use Pimple\Container;
// DataProvider decides what data should be provided to the service
class DataProvider {
public function getData(){
return ['a' => rand(1, 10), 'b' => rand(1, 10), 'c' => rand(1, 10), ];
}
}
class SomeService
{
private $dataProvider;
public function __construct(DataProvider $dataProvider){
$this->dataProvider=$dataProvider;
}
public function getJsonString():string{
return json_encode($this->dataProvider->getData());
}
}
$container=new Container();
// Use pimple factory method to create new service instance, instead of creatng a custom function
$container['getServiceSometimeInTheFuture'] = $container->factory(function (Container $c):SomeService {
return new SomeService($c['dataProvider']);
});
$container['dataProvider'] = function() {
return new DataProvider;
};
$service = $container['getServiceSometimeInTheFuture'];
// Demonstrate how THE SAME INSTANCE will have different data every time
echo("\n" . $service->getJsonString());
echo("\n" . $service->getJsonString());
echo("\n" . $service->getJsonString());
echo("\n" . $service->getJsonString());
使用 Pimple 的raw()
方法。
$container->raw('someService')($container, $someFutureData);
需要設置該服務以接受新數據。
$container['someService'] = $container->factory(function ($c, $data) {
return new SomeService($c['myPdo'], $data);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.