<?php declare(strict_types=1);
namespace Onion\Framework\Collection;

use Onion\Framework\Hydrator\Interfaces\HydratableInterface;

class HydratableCollection implements \IteratorAggregate
{
    private $items;
    private $entityClass;

    public function __construct(iterable $items, string $entity)
    {
        $this->items = $items;
        if (!in_array(HydratableInterface::class, class_implements($entity), true)) {
            throw new \InvalidArgumentException(
                "Provided '{$entity}' does not exist or does not implement: " .
                    HydratableInterface::class
            );
        }

        $this->entityClass = $entity;
    }

    public function getIterator()
    {
        $entity = (new \ReflectionClass($this->entityClass))->newInstance();

        return new CallbackCollection($this->items, function ($item, $key) use ($entity) {
            /** @var HydratableInterface $entity */
            return $entity->hydrate($item);
        });
    }
}

<?php declare(strict_types=1);
namespace Onion\Framework\Collection;

use Onion\Framework\Hydrator\Interfaces\HydratableInterface;

class HydratableCollection extends CallbackCollection
{
    private $items;
    private $entityClass;

    public function __construct(iterable $items, string $entity)
    {
        if (!class_exists($entity)) {
            throw new \InvalidArgumentException(
                "Provided entity '{$entity}' does not exist"
            );
        }
        $reflection = new \ReflectionClass($this->entityClass);
        if (!$reflection->implementsInterface(HydratableInterface::class)) {
            throw new \InvalidArgumentException(
                "Provided '{$entity}' does not implement: " . HydratableInterface::class
            );
        }

        $prototype = $reflection->newInstance();
        parent::__construct($items, function ($item, $key) use ($prototype) {
            /** @var HydratableInterface $prototype */
            return $prototype->hydrate($item);
        });
    }
}

Make collection base instance of hydratable collection
Make collection base instance of hydratable collection
