public function dispatch(): Router
    {
        $this->prepare();

        $method = $this->request->getMethod();
        $scheme = $this->request->getUri()->getScheme();
        $domain = substr($this->request->getUri()->getHost(), strlen($scheme.'://'));
        $uri = $this->request->getUri()->getPath();

        sort($this->routes, SORT_DESC);

        foreach ($this->routes as $route) {
            $parameters = [];

            if (
                $this->compareMethod($route->getMethod(), $method) &&
                $this->compareDomain($route->getDomain(), $domain) &&
                $this->compareUri($route->getUri(), $uri, $parameters)
            ) {
                $this->currentRoute = $route;

                $this->publisher->publish($this->run($route, $parameters));

                return $this;
            }
        }

        throw new RouteNotFoundException();
    }