phpdependency-injectionphp-imagine

DI with multiple intantiations of injected class


I'm using the Imagine library for some image live editing and am running up against a wall understanding how to decouple classes that I might need to build multiple instances of dynamically.

Contrived Example

namespace App;

use Imagine\Image\{ Point, ImagineInterface };
use Imagine\Image\Palette\PaletteInterface;

class Image 
{
    protected $imagine;
    protected $palette;

    public function __construct(ImagineInterface $imagine, PaletteInterface $palette)
    {
        $this->imagine = $imagine;
        $this->palette = $palette;
    }

    public function buildImage($args)
    {
        $image = $this->imagine->open('some/file/path');
        $font = $this->imagine->font('some/font/path', 20, $this->palette->color('#000'));

        /* how to inject these when x/y are dynamically set? */
        $point1 = new Point($args['x1'], $args['y1']);
        $point2 = new Point($args['x2'], $args['y2']);

        $image->draw()->text('example one', $font, $point1);
        $image->draw()->text('example one', $font, $point2);
    }
}

Solution

  • I'm not sure this is the best answer here, but no one has chimed in so I'm going to go with it. I created a factory class that is injected into the image class that takes arguments and returns a new instance of the Imagine Point class like so:

    Factory

    namespace App\Image;
    
    use Imagine\Image\Point;
    
    class PointFactory
    {
        public function create($x, $y)
        {
            return new Point($x, $y);
        }
    }
    

    Image

    namespace App;
    
    use Imagine\Image\ImagineInterface;
    use Imagine\Image\Palette\PaletteInterface;
    use App\Image\PointFactory;
    
    class Image 
    {
        protected $imagine;
        protected $palette;
    
        public function __construct(ImagineInterface $imagine, PaletteInterface $palette, PointFactory $point)
        {
            $this->imagine = $imagine;
            $this->palette = $palette;
            $this->pointFactory = $point;
        }
    
        public function buildImage($args)
        {
            $image = $this->imagine->open('some/file/path');
            $font = $this->imagine->font('some/font/path', 20, $this->palette->color('#000'));
    
            /* how to inject these when x/y are dynamically set? */
            $point1 = $this->pointFactory->create($args['x1'], $args['y1']);
            $point2 = $this->pointFactory->create($args['x2'], $args['y2']);
    
            $image->draw()->text('example one', $font, $point1);
            $image->draw()->text('example one', $font, $point2);
        }
    }
    

    Now to test I create a mock of the factory and pass it in.