我需要初始化一个将注入某些服务的对象。他的一些参数可以在运行时从请求参数中获取。 我应该如何处理这样的动态对象?
我发现的第一种方法是使设置器和传递参数引发使用该对象的服务。但是我觉得这很臭。
第二种方法是将我的对象标记为“综合服务”。因此,我必须在构造函数中准备对象并将其设置为服务容器。
我不确定这是最好的方法。有人可以建议我在这种情况下采取正确的做法吗?
第一种方法的伪代码示例:
class Storage {
private $path;
private $project;
public function __construct($path) {
$this->path = $path;
}
public function setProject($project): void {
$this->project = $project;
}
public function showFullPath() {
echo "Full path: {$this->path}/{$this->project}";
}
}
class Service {
private $storage;
public function __construct(Storage $storage) {
$this->storage = $storage;
}
public function doSomething($project) {
$this->storage->setProject($project);
$this->storage->showFullPath();
}
}
// in controller
$service = $container->get('Service');
$service->doSomething($project);
第二种方法的伪代码示例:
class Storage {
private $path;
private $project;
public function __construct($path, $project) {
$this->path = $path;
$this->project = $project;
}
public function showFullPath() {
echo "Full path: {$this->path}/{$this->project}";
}
}
class Service {
private $storage;
public function __construct(Storage $storage) {
$this->storage = $storage;
}
public function doSomething() {
$this->storage->showFullPath();
}
}
// in controller
$storage = new Storage($path, $project);
$container->set('Storage', $storage);
$service = $container->get('Service');
$service->doSomething();
答案 0 :(得分:0)
如果从请求中检索到您需要的参数,为什么不将请求堆栈注入Storage
,然后在showFullPath
上从请求的堆栈主请求中获取所需的参数?
use Symfony\Component\HttpFoundation\RequestStack;
class Storage {
private $path;
private $requestStack;
public function __construct($path, RequestStack $requestStack) {
$this->path = $path;
$this->requestStack = $requestStack;
}
public function showFullPath() {
$project = $this->requestStack->getMasterRequest()->getYourParametersHereFromRequest();
echo "Full path: {$this->path}/{$project";
}
}
答案 1 :(得分:0)
我同意gvf的观点,在这种情况下,使用RequestStack方法是一个很好的解决方案。但是,如果您坚持使用控制器中的请求对象,则可以引入工厂服务来创建存储对象:
class StorageFactory
{
public function createStorage(Request $request) : Storage
{
// ... create $storage from $request
return $storage;
}
}
class Service
{
public function doSomething(Storage $storage)
{
// ...
}
}
// in your controller
$storage = $container->get("storage_factory")->createStorage($request);
$container->get('Service')->doSomething($storage);
如您所见,您将必须将$storage
对象作为参数传递给doSomething
方法。无法在构造函数中进行设置,因为您明确希望在设置服务后创建$storage
对象。
顺便说一句:setter注入很糟糕,因为它允许服务处于不一致状态。尽可能避免使用它(以及一般的塞特犬)。