繁体   English   中英

疙瘩和动态构造函数注入

[英]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对象的属性以及上传的临时图像的属性来保存上传图像的新安全版本。 ImageUploaderJPEGImageSaver以安全地存储上传的图像。

问题是我有三个与控制器紧密耦合的类,我尝试避免这种情况的方法是使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM