diff --git a/lib/classes/PluginController.php b/lib/classes/PluginController.php
index d57a90d6cebd11cadbf91d05d801e281b1d2df6f..867d6697e12c4067b630ef416f912a58893e9627 100644
--- a/lib/classes/PluginController.php
+++ b/lib/classes/PluginController.php
@@ -6,20 +6,20 @@
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of
  * the License, or (at your option) any later version.
+ *
+ * @property StudIPPlugin $plugin
+ * @property callable $_
+ * @property callable $_n
  */
-
 class PluginController extends StudipController
 {
-    public function __construct($dispatcher)
+    public function __construct(PluginDispatcher $dispatcher)
     {
         parent::__construct($dispatcher);
 
-        if (!isset($dispatcher->current_plugin)) {
-            throw new Exception('Plugin missing for plugin controller!');
-        }
         $this->plugin = $dispatcher->current_plugin;
 
-        if ($this->plugin && $this->plugin->hasTranslation()) {
+        if ($this->plugin->hasTranslation()) {
             // Localization
             $this->_ = function ($string) {
                 return call_user_func_array(
@@ -64,7 +64,10 @@ class PluginController extends StudipController
      */
     public function __call($method, $arguments)
     {
-        if (isset($this->_template_variables[$method]) && is_callable($this->_template_variables[$method])) {
+        if (
+            isset($this->_template_variables[$method])
+            && is_callable($this->_template_variables[$method])
+        ) {
             return call_user_func_array($this->_template_variables[$method], $arguments);
         }
         return parent::__call($method, $arguments);
diff --git a/lib/classes/PluginDispatcher.php b/lib/classes/PluginDispatcher.php
new file mode 100644
index 0000000000000000000000000000000000000000..848f4f27fa2f6993dc91a21ab2a9ed14d0babfeb
--- /dev/null
+++ b/lib/classes/PluginDispatcher.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * This is a specialized dispatcher for plugins.
+ *
+ * @author Jan-Hendrik Willms <tleilax+studip@gmail.com>
+ * @license GPL2 or any later version
+ * @since Stud.IP 6.0
+ */
+class PluginDispatcher extends StudipDispatcher
+{
+    public StudIPPlugin $current_plugin;
+
+    public function __construct(
+        \Psr\Container\ContainerInterface $container,
+        StudIPPlugin $plugin
+    ) {
+        parent::__construct($container);
+
+        $this->current_plugin = $plugin;
+
+        $this->trails_root = $plugin->getPluginPath();
+        $this->trails_uri = rtrim(PluginEngine::getLink($this->current_plugin, [], null, true), '/');
+        $this->default_controller = 'index';
+    }
+}
diff --git a/lib/plugins/core/StudIPPlugin.php b/lib/plugins/core/StudIPPlugin.php
index 6642dbdc989ab4ea2dcf8fae935dcb402ce0bcc9..cbcac648c136ddae7d7971c9001ebd6c2d53439d 100644
--- a/lib/plugins/core/StudIPPlugin.php
+++ b/lib/plugins/core/StudIPPlugin.php
@@ -196,13 +196,8 @@ abstract class StudIPPlugin
         $action = $args[0] !== '' ? array_shift($args).'_action' : 'show_action';
 
         if (!method_exists($this, $action)) {
-            $dispatcher = app(\Trails\Dispatcher::class);
-            $dispatcher->trails_root = $this->getPluginPath();
-            $dispatcher->trails_uri = rtrim(PluginEngine::getLink($this, [], null, true), '/');
-            $dispatcher->default_controller = 'index';
-            $dispatcher->current_plugin = $this;
             try {
-                $dispatcher->dispatch($unconsumed_path);
+                app(PluginDispatcher::class, ['plugin' => $this])->dispatch($unconsumed_path);
             } catch (Trails\Exceptions\UnknownAction $exception) {
                 if (count($args) > 0) {
                     throw $exception;