Thanks for reply @Izo,
It seems that in your example you need to define routes manually each time.
Not the case I'm looking for.
In my Module.php I load services dynamically:
public function registerServices(DiInterface $di)
    {
        // list of services that should be defined
        $services = [
            '\Modules\Tools\Services\ConfigService',
            '\Modules\Tools\Services\DispatcherService',
            '\Modules\Common\Services\ModelsDataService',
            '\Modules\Common\Services\SessionService',
            '\Modules\Common\Services\UrlService',
            '\Modules\Common\Services\ViewService',
        ];
        // iterate over services and define/set them
        foreach($services as $serviceNameSpace){
            /** @var \Modules\Common\Services\AbstractService $service */
            $service = new $serviceNameSpace;
            $service->define();
        }
    }
Views service contains:
        $this->_calls = [
            // set views directory
            [
                'method'    => 'setViewsDir',
                'arguments' => [
                    [
                        'type'  => 'parameter',
                        'value' => $this->_di->get('config')->application->dirs->views
                    ]
                ]
            ],
            // set template engine
            [
                'method' => 'registerEngines',
                'arguments' => [
                    [
                        'type' => 'parameter',
                        'value' => [
                            '.volt' => function(){
                                $volt = new \Phalcon\Mvc\View\Engine\Volt($this->resolve(), $this->_di);
                                $volt->setOptions([
                                    'compiledPath'      => $this->_di->get('config')->application->dirs->cache,
                                    'compiledSeparator' => '_'
                                ]);
                                return $volt;
                            },
                            '.phtml' => 'Phalcon\Mvc\View\Engine\Php'
                        ]
                    ]
                ]
            ]
        ];
Router service contains:
protected $_calls = [
        [
            'method'    => 'setDefaultModule',
            'arguments' => [
                [
                    'type'  => 'parameter',
                    'value' => 'tools'
                ]
            ]
        ],
        [
            'method' => 'add',
            'arguments' => [
                [
                    'type' => 'parameter',
                    'value' => '/:module/:controller/:action/:params'
                ],
                [
                    'type' => 'parameter',
                    'value' => [
                        'module'     => 1,
                        'controller' => 2,
                        'action'     => 3,
                        'params'     => 4
                    ]
                ]
            ]
        ],
        [
            'method'    => 'removeExtraSlashes',
            'arguments' => [
                [
                    'type'  => 'parameter',
                    'value' => true
                ]
            ]
        ]
    ];
$this->_calls /  protected $_calls - is an array that will be passed as setter injection:
https://docs.phalcon.io/en/latest/reference/di.html#setter-injection