executeHandlerAttributes( $handlerClass, $handlerMethod, BeforeExecute::class, $command ); } /** * Führt "After"-Attribute für einen Handler aus * * @param string $handlerClass Handler-Klasse * @param string $handlerMethod Handler-Methode * @param object $command Command/Query-Objekt * @param mixed $result Ergebnis der Handler-Ausführung */ public function executeAfter( string $handlerClass, string $handlerMethod, object $command, mixed $result ): void { $context = AttributeExecutionContext::forMethod( $this->container, ClassName::create($handlerClass), MethodName::create($handlerMethod) ); // Füge Result zum Context hinzu $context = new AttributeExecutionContext( container: $context->container, targetClass: $context->targetClass, targetMethod: $context->targetMethod, targetProperty: $context->targetProperty, targetValue: $result, additionalData: array_merge($context->additionalData, [ 'command' => $command, 'result' => $result, ]) ); $this->executeHandlerAttributesForContext( $handlerClass, $handlerMethod, AfterExecute::class, $context ); } /** * Führt "OnError"-Attribute für einen Handler aus * * @param string $handlerClass Handler-Klasse * @param string $handlerMethod Handler-Methode * @param object $command Command/Query-Objekt * @param \Throwable $exception Aufgetretene Exception */ public function executeOnError( string $handlerClass, string $handlerMethod, object $command, \Throwable $exception ): void { $context = AttributeExecutionContext::forMethod( $this->container, ClassName::create($handlerClass), MethodName::create($handlerMethod) ); // Füge Exception zum Context hinzu $context = new AttributeExecutionContext( container: $context->container, targetClass: $context->targetClass, targetMethod: $context->targetMethod, targetProperty: $context->targetProperty, targetValue: null, additionalData: array_merge($context->additionalData, [ 'command' => $command, 'exception' => $exception, ]) ); $this->executeHandlerAttributesForContext( $handlerClass, $handlerMethod, OnError::class, $context ); } /** * Führt Attribute eines bestimmten Typs für einen Handler aus */ private function executeHandlerAttributes( string $handlerClass, string $handlerMethod, string $attributeClass, object $command ): void { $context = AttributeExecutionContext::forMethod( $this->container, ClassName::create($handlerClass), MethodName::create($handlerMethod) ); // Füge Command zum Context hinzu $context = new AttributeExecutionContext( container: $context->container, targetClass: $context->targetClass, targetMethod: $context->targetMethod, targetProperty: $context->targetProperty, targetValue: $command, additionalData: array_merge($context->additionalData, [ 'command' => $command, ]) ); $this->executeHandlerAttributesForContext( $handlerClass, $handlerMethod, $attributeClass, $context ); } /** * Führt Attribute für einen Handler mit gegebenem Context aus */ private function executeHandlerAttributesForContext( string $handlerClass, string $handlerMethod, string $attributeClass, AttributeExecutionContext $context ): void { $attributes = $this->discoveryRegistry->attributes->get($attributeClass); foreach ($attributes as $discovered) { // Prüfe ob Attribut zu diesem Handler gehört if (!$discovered->className->equals(ClassName::create($handlerClass))) { continue; } if ($discovered->methodName === null || !$discovered->methodName->equals(MethodName::create($handlerMethod))) { continue; } // Führe Attribut aus $this->attributeRunner->executeAttribute($discovered, $context); } } }