I was working on a suitable example of the CoR(Chain-of-responsibility) pattern. I learned that it is often used as middleware layer in MVC.
I am trying to write a middleware layer suitable for the pattern.
I have set my scenario regarding the implementation of the pattern as follows: The classes defined in the controller method as Annotations are linked to each other with chains, and each class performs a task and moves on to the next task. CoR(Chain-of-responsibility) pattern implementation known so far.
When I look at the examples, none of the classes used as middleware have been injected with Depency injection.
My scenario is as follows: An "@Middleware()" annonation is defined to the Controller method. Sample
/**
* @Route("/", name="test")
* @Middleware({"App\Middleware\MiddlewareOne","App\Middleware\MiddlewareTwo"})
*/
public function test()
Then I get annotations in the "onKernelController" method with ControllerListener and create the classes defined here with a foreach loop and connect them to each other.
Below you will see the sample code blocks, respectively.
The problem I'm having here is How can I give the ContainerInterface or a Service class that I created in the constructor of the MiddlewareOne class to the constructor of this object?(I do not know which services are coming, a fixed service is not coming)
class ControllerListener
{
/**
* @param \Symfony\Component\HttpKernel\Event\ControllerEvent $controllerEvent
*/
public function onKernelController(ControllerEvent $controllerEvent)
{
MiddlewareManager::handle($controllerEvent);
}
}
class MiddlewareManager
{
public static function handle(ControllerEvent $controllerEvent)
{
$containerBuilder = new ContainerBuilder();
if (!is_array($controllers = $controllerEvent->getController())) {
return;
}
$reader = new AnnotationReader();
$request = $controllerEvent->getRequest();
$content = $request->getContent();
[ $controller, $methodName ] = $controllers;
$reflectionClass = new \ReflectionClass($controller);
$classAnnotation = $reader
->getClassAnnotation($reflectionClass, Middleware::class);
$reflectionObject = new \ReflectionObject($controller);
$reflectionMethod = $reflectionObject->getMethod($methodName);
$methodAnnotation = $reader
->getMethodAnnotation($reflectionMethod, Middleware::class);
if (!($classAnnotation || $methodAnnotation)) {
return;
}
$middlewareList = $classAnnotation->getMiddleware()['value'];
$middleware = null;
$temp = null;
foreach ($middlewareList as $class){
if ($middleware === null){
$middleware = new $class();
$temp = $middleware;
continue;
}
$class = new $class();
$temp->next($class);
$temp = $class;
}
return $middleware;
}
}
class DumpOneMiddleware implements Middleware
{
/** @var \App\Middleware\Middleware */
private $next;
/** @var \App\Service\ExampleService */
private $exampleService;
public function __construct(ExampleService $exampleService)
{
$this->exampleService = $exampleService;
}
/**
* @param \App\Middleware\Middleware $next
* @return \App\Middleware\Middleware
*/
public function next(Middleware $next)
{
$this->next = $next;
return $next;
}
/**
* @param \Symfony\Component\HttpFoundation\Request $request
*/
public function handle(Request $request)
{
if (!$this->next) {
return true;
}
return $this->next->handle($request);
}
}
Here I can export Container object via ControllerListener (to all middleware classes). But if I want to add another service, how can I do it?
When I examined these and similar topics, I came to the conclusion that I should look at the strategy pattern and Compailer Pass issues. But these topics didn't help me much or I couldn't understand.
I would be very grateful if you could indicate the deficiencies or mistakes in the scenario I applied and show with an example how I can inject Dependecy into the objects I created dynamically.
source https://stackoverflow.com/questions/69350780/cor-pattern-appropriate-dependency-injection-with-symfony
Comments
Post a Comment