22
33namespace Nuxtifyts \PhpDto \Contexts ;
44
5+ use Nuxtifyts \PhpDto \Attributes \Class \WithNormalizer ;
56use Nuxtifyts \PhpDto \Data ;
67use Nuxtifyts \PhpDto \Exceptions \DataCreationException ;
78use Nuxtifyts \PhpDto \Exceptions \UnsupportedTypeException ;
9+ use Nuxtifyts \PhpDto \Normalizers \Normalizer ;
10+ use ReflectionAttribute ;
811use ReflectionException ;
912use ReflectionParameter ;
1013use ReflectionClass ;
@@ -30,6 +33,9 @@ class ClassContext
3033 /** @var list<string> List of param names */
3134 public readonly array $ constructorParams ;
3235
36+ /** @var array<array-key, class-string<Normalizer>> */
37+ private(set) array $ normalizers = [];
38+
3339 /**
3440 * @param ReflectionClass<T> $reflection
3541 *
@@ -43,6 +49,7 @@ final private function __construct(
4349 static fn (ReflectionParameter $ param ) => $ param ->getName (),
4450 $ this ->reflection ->getConstructor ()?->getParameters() ?? [],
4551 );
52+ $ this ->syncClassAttributes ();
4653 }
4754
4855 public bool $ hasComputedProperties {
@@ -55,22 +62,33 @@ final private function __construct(
5562 }
5663
5764 /**
58- * @param ReflectionClass<T> $reflectionClass
65+ * @param ReflectionClass<T>|class-string<T> $reflectionClass
5966 *
6067 * @throws UnsupportedTypeException
68+ * @throws ReflectionException
6169 */
62- final public static function getInstance (ReflectionClass $ reflectionClass ): static
70+ final public static function getInstance (string | ReflectionClass $ reflectionClass ): static
6371 {
72+ $ instance = self ::$ _instances [self ::getKey ($ reflectionClass )] ?? null ;
73+
74+ if ($ instance ) {
75+ return $ instance ;
76+ }
77+
78+ if (is_string ($ reflectionClass )) {
79+ $ reflectionClass = new ReflectionClass ($ reflectionClass );
80+ }
81+
6482 return self ::$ _instances [self ::getKey ($ reflectionClass )]
65- ?? = new static ($ reflectionClass );
83+ = new static ($ reflectionClass );
6684 }
6785
6886 /**
69- * @param ReflectionClass<T> $reflectionClass
87+ * @param ReflectionClass<T>|class-string<T> $reflectionClass
7088 */
71- private static function getKey (ReflectionClass $ reflectionClass ): string
89+ private static function getKey (string | ReflectionClass $ reflectionClass ): string
7290 {
73- return $ reflectionClass ->getName ();
91+ return is_string ( $ reflectionClass ) ? $ reflectionClass : $ reflectionClass ->getName ();
7492 }
7593
7694 /**
@@ -91,6 +109,17 @@ private static function getPropertyContexts(ReflectionClass $reflectionClass): a
91109 return $ properties ;
92110 }
93111
112+ private function syncClassAttributes (): void
113+ {
114+ foreach ($ this ->reflection ->getAttributes (WithNormalizer::class) as $ withNormalizerAttribute ) {
115+ /** @var ReflectionAttribute<WithNormalizer> $withNormalizerAttribute */
116+ $ this ->normalizers = array_values ([
117+ ...$ this ->normalizers ,
118+ ...$ withNormalizerAttribute ->newInstance ()->classStrings
119+ ]);
120+ }
121+ }
122+
94123 /**
95124 * @throws ReflectionException
96125 *
0 commit comments