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,75 @@ 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+ return ;
95+ }
96+
97+ // Validate the transformer
98+ if (gettype ($ transformerClassName ) !== 'string ' ) {
99+ throw new InvalidTransformerClassNameException ;
100+ }
101+
102+ // Instantiate the transformer
103+ if ($ this ->dependencyInjectionHandler ) {
104+ $ transformerInstance = ($ this ->dependencyInjectionHandler )($ transformerClassName );
105+
106+ if (!($ transformerInstance instanceof Transformer)) {
107+ throw new InvalidTransformerClassException ($ transformerClassName );
108+ }
109+ } else {
78110 try {
79- $ transformerInstance = DI ::make ($ transformer );
111+ $ transformerInstance = DI ::make ($ transformerClassName );
80112 } catch (Error |Exception ) {
81- throw new TransformerNotFoundException ($ transformer );
113+ throw new TransformerNotFoundException ($ transformerClassName );
82114 }
115+ }
83116
84- // Validate the transformer
85- $ isTransformer = $ transformerInstance instanceof Transformer;
86- if (!$ isTransformer ) {
87- throw new InvalidTransformerClassException ($ transformer );
88- }
89- assert ($ transformerInstance instanceof Transformer);
117+ // Validate the transformer
118+ $ isTransformer = $ transformerInstance instanceof Transformer;
119+ if (!$ isTransformer ) {
120+ throw new InvalidTransformerClassException ($ transformerClassName );
121+ }
90122
91- // Create transformer container
92- $ transformerContainer = DI ::make (TransformerContainer::class, [
93- 'transformerInstance ' => $ transformerInstance ,
94- ]);
123+ // Create transformer container
124+ $ transformerContainer = DI ::make (TransformerContainer::class, [
125+ 'transformerInstance ' => $ transformerInstance ,
126+ ]);
95127
96- // Create a reflection of the transformer
97- $ transformerRefClass = new BaseReflectionClass ($ transformerInstance );
128+ // Create a reflection of the transformer
129+ $ transformerRefClass = new BaseReflectionClass ($ transformerInstance );
98130
99- $ filePath = $ transformerRefClass ->getFileName ();
100- $ this ->transformerContainers [$ filePath ] = $ transformerContainer ;
101- }
131+ $ filePath = $ transformerRefClass ->getFileName ();
132+ $ this ->transformerContainers [$ filePath ] = $ transformerContainer ;
102133 }
103134
104135 // endregion
0 commit comments