Pre-Populate $wp_query settings with custom rewrite rules and custom template_redirect

I’ve probably found the solution for the above problem. To pre-populate the global variable $wp_query you have to run the query_posts() function with the correct arguments and reset the $wp_query->post with the function wp_reset_postdata(). This must be done on the template_redirect hook or earlier.

class Webeo_Download {
    protected $downloadId;
    protected $action;

    public function setup() {
        // ...
        add_action('template_redirect', array($this, '_requestHandler'), 9);
    }

    public function _requestHandler() {
        $this->action = get_query_var('action');
        $this->downloadId = get_query_var('download');

        // ... load appropirate action method based on the query variable "action". See code example in the question above. 
    }

    public function actionView() {
        // Check permissions
        if(!is_user_logged_in()) {
            wp_redirect(wp_login_url());
            exit;
        }

        // Populate $wp_query for single download view
        global $wp_query;
        $args = array('post_type' => 'download', 'p' => $this->downloadId);
        query_posts($args);
        wp_reset_postdata();

        // Load the template
    }

    public function actionIndex() {
        // Do the same for all other action methods
    }

    public function actionAdd() {
        // ...
    }

    public function actionEdit() {
        // ...
    }

    public function actionDelete() {
        // ...
    }

    public function actionDownload() {
        // ...
    }
}

If someone has a better approach, please let me know!