[英]Pimple and dynamic constructor injection
我有一個關於疙瘩和動態構造函數注入的問題。
說我有一個MVC框架,我想做一些像圖像上傳。 半DI的方式是這樣的:
class ImageUploadController
{
public function upload()
{
$targetImage = new Image(1920, 1080, 75, 'jpg', 'save/path');
$imageSaver = new JPEGImageSaver($targetImage);
$imageUploader = new ImageUploader($imageSaver);
$imageUploader->upload('myUploadfield');
}
}
基本上Image
是我想要創建和保存的圖像屬性的簡單容器。 JPEGImageSaver
利用imagecreatefromjpeg()
, imagecopyresized()
和imagejpeg()
以及Image
對象的屬性以及上傳的臨時圖像的屬性來保存上傳圖像的新安全版本。 ImageUploader
與JPEGImageSaver
以安全地存儲上傳的圖像。
問題是我有三個與控制器緊密耦合的類,我嘗試避免這種情況的方法是使用Pimple,然后將Pimple傳遞給控制器。
class ImageUploadController
{
public function upload()
{
$targetImage = $this->app['Image'];
$targetImage->setWidth(1920);
$targetImage->setHeight(1080);
$targetImage->setQuality(75);
$targetImage->setExtension('jpg');
$targetImage->setSavePath('save/path');
$imageSaver = $this->app['JPEGImageSaver'];
$imageSaver->setTargetImage($targetImage);
$imageUploader = $this->app['ImageUploader'];
$imageUploader->setImageSaver($imageSaver);
$imageUploader->upload('myUploadField');
}
}
但正如您所看到的,使用Pimple將依賴項注入我的控制器已經使它們比以前更加復雜。 主要問題是我沒有在Pimple中看到在請求期間為對象設置構造函數值的方法,因此需要一堆用於Image
對象的setter。
這個問題有一個共同的解決方案嗎? 我想過將Pimple包裝在一個解析容器中,讓我傳入構造函數參數,但問題是我的IDE不會指出如何通過智能感知來構造各種對象。 我也有點懷疑有多少可測試的$this->app['something']
甚至讓我的控制器。
控制器甚至需要可測試嗎? 如果是這樣,我可以將Image
對象視為值對象嗎?
有什么想法嗎?
Pimple是存儲價值或服務的容器。 應用程序要求Pimple檢索諸如會話對象之類的服務。
如果在整個應用程序中使用圖像類並具有精確定義,
<?php
$targetImage = new Image(1920, 1080, 75, 'jpg', 'save/path');
然后你可以問Pimple存儲這個定義。
<?php
// define image service
$container['image'] = function ($c) {
return new Image(1920, 1080, 75, 'jpg', 'save/path');
};
如果您的應用程序中有不同的圖像大小,則可以執行以下操作:
<?php
// define image service
$container['bigImage'] = function ($c) {
return new Image(1920, 1080, 75, 'jpg', 'save/path');
};
$container['smallImage'] = function ($c) {
return new Image(200, 200, 75, 'jpg', 'save/path');
};
您可以更進一步並存儲Image類的參數並重新使用它們。
<?php
$container['imageParams'] = [
'width' => 1920,
'height' => 1080,
'type' => 'jpg',
'quality' => 75
];
// define image service
$container['image'] = function ($c) {
$image = $c['imageParams'];
return new Image($image['width'],
$image['height'],
$image['quality'],
$image['type'],
'save/path'
);
};
目前在Pimple中,您無法在檢索服務時傳遞參數:
<?php
$this->app['image'](1920, 1080, 75, 'jpg', 'save/path');
您需要擴展Pimple才能實現此功能。
但是,您可以在控制器類中創建一個工廠方法,該方法將修改存儲在Pimple中的圖像參數,然后調用圖像服務以使用您的特定參數創建圖像對象,然后將存儲的參數恢復為原始值。
<?php
class ImageUploadController {
protected function imageFactory($width, $height, $type, $quality) {
// Store original parameters
$origin = $this->app['imageParams'];
// Override the original parameters
$this->app['imageParams']['width'] = $width;
$this->app['imageParams']['height'] = $height;
$this->app['imageParams']['quality'] = $quality;
$this->app['imageParams']['type'] = $type;
// Get image class
$image = $this->app['image'];
// Rest image parameters
$this->app['imageParams'] = $origin;
return $image;
}
public function upload()
{
$targetImage = $this->imageFactory(1920, 1080, 75, 'jpg');
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.