22/** @noinspection PhpPropertyOnlyWrittenInspection */
33namespace Okapi \CodeTransformer \Core \Container ;
44
5+ use Closure ;
56use Error ;
67use Exception ;
78use Okapi \CodeTransformer \Core \DI ;
89use Okapi \CodeTransformer \Core \Exception \Transformer \InvalidTransformerClassException ;
10+ use Okapi \CodeTransformer \Core \Exception \Transformer \InvalidTransformerClassNameException ;
911use Okapi \CodeTransformer \Core \Exception \Transformer \TransformerNotFoundException ;
1012use Okapi \CodeTransformer \Core \ServiceInterface ;
1113use Okapi \CodeTransformer \Transformer ;
@@ -32,6 +34,11 @@ class TransformerManager implements ServiceInterface
3234 */
3335 private array $ transformerContainers = [];
3436
37+ /**
38+ * @var ?Closure(class-string<Transformer>): Transformer
39+ */
40+ private ?Closure $ dependencyInjectionHandler = null ;
41+
3542 // region Pre-Initialization
3643
3744 /**
@@ -54,51 +61,73 @@ public function addTransformers(array $transformers): void
5461 // region Initialization
5562
5663 /**
57- * Register the transformer container.
58- *
59- * @return void
64+ * @param null|(Closure(class-string<Transformer>): Transformer) $dependencyInjectionHandler
6065 */
66+ public function registerCustomDependencyInjectionHandler (
67+ ?Closure $ dependencyInjectionHandler
68+ ): void {
69+ $ this ->dependencyInjectionHandler = $ dependencyInjectionHandler ;
70+ }
71+
6172 public function register (): void
6273 {
6374 $ this ->loadTransformers ();
6475 }
6576
77+ private function loadTransformers (): void
78+ {
79+ foreach ($ this ->transformers as $ transformer ) {
80+ $ this ->loadTransformer ($ transformer );
81+ }
82+ }
83+
6684 /**
67- * Get the transformer instances.
68- *
69- * @return void
85+ * @param class-string<Transformer> $transformerClassName
7086 *
7187 * @noinspection PhpUnhandledExceptionInspection
7288 * @noinspection PhpDocMissingThrowsInspection
7389 */
74- private function loadTransformers ( ): void
90+ private function loadTransformer ( mixed $ transformerClassName ): void
7591 {
76- foreach ($ this ->transformers as $ transformer ) {
77- // Instantiate the transformer
92+ // Check if the transformer is already loaded
93+ if (array_key_exists ($ transformerClassName , $ this ->transformerContainers )) {
94+ // @codeCoverageIgnoreStart
95+ return ;
96+ // @codeCoverageIgnoreEnd
97+ }
98+
99+ // Validate the transformer
100+ if (gettype ($ transformerClassName ) !== 'string ' ) {
101+ throw new InvalidTransformerClassNameException ;
102+ }
103+
104+ // Instantiate the transformer
105+ if ($ this ->dependencyInjectionHandler ) {
106+ $ transformerInstance = ($ this ->dependencyInjectionHandler )($ transformerClassName );
107+ } else {
78108 try {
79- $ transformerInstance = DI ::make ($ transformer );
109+ $ transformerInstance = DI ::make ($ transformerClassName );
80110 } catch (Error |Exception ) {
81- throw new TransformerNotFoundException ($ transformer );
111+ throw new TransformerNotFoundException ($ transformerClassName );
82112 }
113+ }
83114
84- // Validate the transformer
85- $ isTransformer = $ transformerInstance instanceof Transformer;
86- if (!$ isTransformer ) {
87- throw new InvalidTransformerClassException ($ transformer );
88- }
89- assert ($ transformerInstance instanceof Transformer);
115+ // Validate the transformer
116+ $ isTransformer = $ transformerInstance instanceof Transformer;
117+ if (!$ isTransformer ) {
118+ throw new InvalidTransformerClassException ($ transformerClassName );
119+ }
90120
91- // Create transformer container
92- $ transformerContainer = DI ::make (TransformerContainer::class, [
93- 'transformerInstance ' => $ transformerInstance ,
94- ]);
121+ // Create transformer container
122+ $ transformerContainer = DI ::make (TransformerContainer::class, [
123+ 'transformerInstance ' => $ transformerInstance ,
124+ ]);
95125
96- // Create a reflection of the transformer
97- $ transformerRefClass = new BaseReflectionClass ($ transformerInstance );
126+ // Create a reflection of the transformer
127+ $ transformerRefClass = new BaseReflectionClass ($ transformerInstance );
98128
99- $ filePath = $ transformerRefClass ->getFileName ();
100- $ this ->transformerContainers [$ filePath ] = $ transformerContainer ;
101- }
129+ $ filePath = $ transformerRefClass ->getFileName ();
130+ $ this ->transformerContainers [$ filePath ] = $ transformerContainer ;
102131 }
103132
104133 // endregion
0 commit comments