diff --git a/src/Factory.php b/src/Factory.php index a11f1d80..ed333ae0 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -28,11 +28,23 @@ abstract class Factory /** @var Attributes[] */ private array $attributes; + /** + * Memoization of normalized parameters + * + * @internal + * @var Parameters|null + */ + protected array|null $normalizedParameters = null; + // keep an empty constructor for BC public function __construct() { } + public function __clone(): void + { + $this->normalizedParameters = null; + } /** * @param Attributes $attributes @@ -144,6 +156,16 @@ final protected static function faker(): Faker\Generator return Configuration::instance()->faker; } + /** + * Override to adjust default attributes & config. + * + * @return static + */ + protected function initialize(): static + { + return $this; + } + /** * @internal * @@ -170,16 +192,6 @@ final protected function normalizeAttributes(array|callable $attributes = []): a ); } - /** - * Override to adjust default attributes & config. - * - * @return static - */ - protected function initialize(): static - { - return $this; - } - /** * @internal * @@ -189,7 +201,7 @@ protected function initialize(): static */ protected function normalizeParameters(array $parameters): array { - return array_combine( + return $this->normalizedParameters = array_combine( array_keys($parameters), \array_map($this->normalizeParameter(...), array_keys($parameters), $parameters) ); diff --git a/src/Persistence/PersistentObjectFactory.php b/src/Persistence/PersistentObjectFactory.php index 2bd83ffd..eb54b175 100644 --- a/src/Persistence/PersistentObjectFactory.php +++ b/src/Persistence/PersistentObjectFactory.php @@ -226,7 +226,7 @@ final public function create(callable|array $attributes = []): object $this->tempAfterPersist = []; if ($this->afterPersist) { - $attributes = $this->normalizeAttributes($attributes); + $attributes = $this->normalizedParameters ?? throw new \LogicException('Factory::$normalizedParameters has not been initialized.'); foreach ($this->afterPersist as $callback) { $callback($object, $attributes); diff --git a/tests/Integration/ObjectFactoryTest.php b/tests/Integration/ObjectFactoryTest.php index 4dbaf095..96f3ca87 100644 --- a/tests/Integration/ObjectFactoryTest.php +++ b/tests/Integration/ObjectFactoryTest.php @@ -44,4 +44,20 @@ public function can_create_non_service_factories(): void $this->assertSame('router-constructor', $object->object->getProp1()); } + + /** + * @test + */ + public function can_create_different_objects_based_on_same_factory(): void + { + $factory = Object1Factory::new(['prop1' => 'first object']); + $object1 = $factory->create(); + self::assertSame('first object-constructor', $object1->getProp1()); + + $object2 = $factory->create(['prop1' => 'second object']); + self::assertSame('second object-constructor', $object2->getProp1()); + + $object3 = $factory->with(['prop1' => 'third object'])->create(); + self::assertSame('third object-constructor', $object3->getProp1()); + } }