/// <summary>
        /// Retrieves the list of backups in the storage provider and populates the collection. Clears any existing
        /// elements in the collection.
        /// </summary>
        public async Task GetExistingBackups()
        {
            using var scope = _scopeFactory.CreateScope();
            var storage  = scope.ServiceProvider.GetService <IStorageService>();
            var existing = await storage.GetExistingFiles();

            _list.Clear();

            var startChar = _keyName.Length + 1;

            foreach (var file in existing.Where(f => f.Item1.StartsWith(_keyName)))
            {
                try
                {
                    var parseText = file.Item1.Substring(startChar).Split('.')[0];
                    var timeStamp = DateTime.ParseExact(parseText, _dateTimeFormat, CultureInfo.InvariantCulture);
                    var backup    = new DbBackup(file.Item1, timeStamp, file.Item2);
                    _list[file.Item1] = backup;
                }
                catch (Exception)
                {
                    // Exceptions here are ignored. Because we are reading directly from the storage backend we're
                    // going to have every parse error from every file show up as an exception.
                }
            }
        }
        public async Task RetrieveBackup(DbBackup backup, string destinationPath)
        {
            using var scope = _scopeFactory.CreateScope();
            var storage = scope.ServiceProvider.GetService <IStorageService>();

            try
            {
                await storage.DownloadFile(backup.FileName, destinationPath);
            }
            catch (Exception e)
            {
                _logger.Log(LogLevel.Error, e.Message);
                throw;
            }
        }
        /// <summary>
        /// Add a backup file to the collection. This should be in the form of a dumped file with a unique but
        /// irrelevant name that has already been compressed. The collection will manage the file's final name in the
        /// storage backend.
        /// </summary>
        /// <param name="file">A FileInfo object pointing to the file to be added to the collection</param>
        /// <param name="timeStamp">The timestamp from the database when the backup was taken</param>
        /// <returns></returns>
        public async Task AddBackup(FileInfo file, DateTime timeStamp)
        {
            var timeText = timeStamp.ToString(_dateTimeFormat);
            var name     = $"{_keyName}-{timeText}.sql.gz";

            using var scope = _scopeFactory.CreateScope();
            var storage = scope.ServiceProvider.GetService <IStorageService>();

            try
            {
                await storage.UploadFile(file.FullName, name);

                var newBackup = new DbBackup(name, timeStamp, (ulong)file.Length);
                _list[name] = newBackup;
                _addSubject.OnNext(newBackup);
            }
            catch (Exception e)
            {
                _logger.Log(LogLevel.Error, e.Message);
                throw;
            }
        }