将范围数据传递到服务容器

问题描述 投票:1回答:1

我希望创建一个新的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());
php service dependency-injection closures pimple
1个回答
0
投票

除了使用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());

如果将来以后需要将数据提供给someService时可以推迟:

<?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());
© www.soinside.com 2019 - 2024. All rights reserved.