'How can factory supply many instances when using DI Container with constructor injection

I am trying to figure out how to write a PHP factory that uses constructor injection via dependency container (DI) that can create many objects.

This is boilerplate code for the factory.

<?php

interface ItemInterface
{
}

enum ItemType: string
{
  case ItemA = ItemA::class;
  case ItemB = ItemB::class;
}

class ItemA implements ItemInterface
{
}

class ItemB implements ItemInterface
{
}

class ItemFactory
{
  protected function __construct()
  {
    // static factory, prevent new instances
  }

  public static function make(ItemType $type): ItemInterface
  {
    return new $type->value();
  }
}

When we want to create a single instance of either Item A or Item B, it seems straight forward to me:

  • type hint against interface to avoid tight coupling
  • use DI Container to inject concrete instance via constructor injection
  • this is configured in DI Container config to avoid calling container directly
  • all external dependencies are clearly outlined in the constructor
class LogicForItemA
{
  // $item is resolved to ItemA via DI Container and constructor injection
  public function __construct(
    protected ItemInterface $item
  ) {
  }
}

When we want to have multiple instances of either ItemA or ItemB, I am not sure how to implement it properly. My concerns are the following

  • it "feels" like doLogic() is now tightly coupled with ItemA
  • dependency on ItemA is now missing from constructor
  • instantiation of ItemA is now "buried" inside method (not even function parameter)
  • with lots of code it will become obscured

class LogicForManyItems
{
  public function __construct(
    protected ItemFactory $factory
  ) {
  }

  public function doLogic()
  {
    $item1 = $this->factory->make(ItemType::ItemA);
    $item2 = $this->factory->make(ItemType::ItemA);
    $item3 = $this->factory->make(ItemType::ItemA);
  }
}

There are legitimate reasons to have a need for many instances of another class but I am not sure how to implement it cleanly or properly when using factory with DI Container that does constructor injection.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source