adjust the metadata code so it archives the following , stores the metadata in the cache as soon as my application starts , the cache gets deleted when the application ends or the cache has been stored longer than 24 hours .
public interface IMetadataCache
{
    ValueTask<ImmutableArray<ProcedureOperation>> GetMetadataForProcedureAsync(string procedureName);
    bool IsInitialized { get; }
}

public sealed class MetadataCache : IMetadataCache, IDisposable
{
    private const string CacheKey = "Procedures_Metadata";
    private static readonly TimeSpan CacheExpiration = TimeSpan.FromHours(24);

    private readonly IMemoryCache _cache;
    private readonly string _connectionString;
    private readonly SemaphoreSlim _initializationSemaphore = new(1, 1);
    private volatile bool _isInitialized;
    private bool _disposed;

    public MetadataCache(IMemoryCache cache, string connectionString)
    {
        _cache = cache ?? throw new ArgumentNullException(nameof(cache));
        _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
    }

    public bool IsInitialized => _isInitialized;

    public async ValueTask<ImmutableArray<ProcedureOperation>> GetMetadataForProcedureAsync(string procedureName)
    {
        ArgumentNullException.ThrowIfNull(procedureName);

        if (!_isInitialized)
        {
            await EnsureInitializedAsync().ConfigureAwait(false);
        }

        if (_cache.TryGetValue(CacheKey, out ConcurrentDictionary<string, ImmutableArray<ProcedureOperation>>? cache) &&
            cache?.TryGetValue(procedureName, out var operations) == true)
        {
            return operations;
        }

        return ImmutableArray<ProcedureOperation>.Empty;
    }

    private async Task EnsureInitializedAsync()
    {
        if (_isInitialized) return;

        await _initializationSemaphore.WaitAsync().ConfigureAwait(false);
        try
        {
            if (_isInitialized) return;

            var metadata = await RetrieveMetadataFromDatabaseAsync().ConfigureAwait(false);

            var dictionary = new ConcurrentDictionary<string, ImmutableArray<ProcedureOperation>>(
                metadata.GroupBy(m => m.ProcedureName, StringComparer.OrdinalIgnoreCase)
                       .ToDictionary(g => g.Key, g => g.ToImmutableArray(), StringComparer.OrdinalIgnoreCase));

            var cacheEntryOptions = new MemoryCacheEntryOptions()
                .SetAbsoluteExpiration(CacheExpiration)
                .RegisterPostEvictionCallback((key, value, reason, state) =>
                {
                    _isInitialized = false;
                });

            _cache.Set(CacheKey, dictionary, cacheEntryOptions);
            _isInitialized = true;
        }
        finally
        {
            _initializationSemaphore.Release();
        }
    }

    private async Task<List<ProcedureOperation>> RetrieveMetadataFromDatabaseAsync()
    {
        const string storedProcedure = "getproceduresoperations";
        var procedureOperations = new List<ProcedureOperation>();

        await using var connection = new OracleConnection(_connectionString);
        await connection.OpenAsync().ConfigureAwait(false);

        await using var command = new OracleCommand(storedProcedure, connection)
        {
            CommandType = CommandType.StoredProcedure
        };

        command.Parameters.Add(new OracleParameter("cv_1", OracleDbType.RefCursor)
        {
            Direction = ParameterDirection.Output
        });

        await using var reader = await command.ExecuteReaderAsync().ConfigureAwait(false);

        var procedureNameOrdinal = reader.GetOrdinal("PROCEDURENAME");
        var operationTypeOrdinal = reader.GetOrdinal("OPERATIONTYPE");
        var affectedTableOrdinal = reader.GetOrdinal("AFFECTEDTABLE");

        while (await reader.ReadAsync().ConfigureAwait(false))
        {
            procedureOperations.Add(new ProcedureOperation
            {
                ProcedureName = reader.GetString(procedureNameOrdinal),
                OperationType = reader.GetString(operationTypeOrdinal),
                AffectedTable = reader.GetString(affectedTableOrdinal)
            });
        }

        return procedureOperations;
    }

    public void Dispose()
    {
        if (_disposed) return;

        _initializationSemaphore.Dispose();
        _disposed = true;
        GC.SuppressFinalize(this);
    }
}
//program.cs snippet
var connectionString = await oAppSettings?.MetadataConfiguration?.DBConnectionString() ?? "";
builder.Services.AddSingleton<IMetadataCache>(provider =>
{
    var memoryCache = provider.GetRequiredService<IMemoryCache>();
    return new MetadataCache(memoryCache, connectionString);
});