Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Oct 21, 2025

Summary

Adds a new ShouldNotStore property to ICacheEntry that allows factory methods in GetOrCreate and GetOrCreateAsync to conditionally suppress storing the computed value in the cache. This enables scenarios where runtime conditions determine whether a value should be cached.

Motivation

In some scenarios, the decision whether to cache a value can only be made during the factory execution. For example:

  • An API call might return a response indicating the data is transient and shouldn't be cached
  • A computation might detect that the result is invalid or incomplete
  • Resource constraints or error conditions may warrant skipping the cache

Previously, there was no way to prevent caching once GetOrCreate/GetOrCreateAsync was called. This PR adds that capability.

Usage Example

var result = await cache.GetOrCreateAsync("api-data", async entry =>
{
    var response = await apiClient.GetDataAsync();
    
    // Don't cache if the API indicates the data is stale
    if (response.IsStale)
    {
        entry.ShouldNotStore = true;
    }
    
    return response.Data;
});

When ShouldNotStore is set to true, the factory's return value is provided to the caller but is not stored in the cache. Subsequent calls will re-execute the factory.

Implementation Details

  • Added bool ShouldNotStore { get; set; } property to ICacheEntry interface
  • Implemented the property in CacheEntry class with a private backing field
  • Modified Dispose() and CommitWithTracking() methods to check the flag before calling SetEntry()
  • No changes needed to GetOrCreate/GetOrCreateAsync - they already use using statements that call Dispose()
  • Added comprehensive tests covering both sync and async scenarios with tracking enabled/disabled

Testing

Added 4 new tests to verify:

  • GetOrCreate with ShouldNotStore=true doesn't cache and re-executes factory
  • GetOrCreateAsync with ShouldNotStore=true doesn't cache and re-executes factory
  • GetOrCreate without the flag (normal behavior) caches as expected
  • GetOrCreateAsync without the flag (normal behavior) caches as expected
  • All scenarios tested with both tracking enabled and disabled

All tests pass (137 total including 4 new tests).

Breaking Changes

None. This is a purely additive change that adds a new optional property to the public API.

Original prompt

Add a flag to CacheEntry (in Microsoft.Extensions.Caching.Memory) that indicates whether the result computed by GetOrCreateAsync, GetOrCreate, and similar cache entry creation methods should be stored in the cache. If, during processing in the factory method, a condition arises that means the cache entry should not be used, this flag can be set, and the entry will not be stored (so subsequent requests will re-execute the factory).

Implementation details:

  • Add a boolean property (e.g., ShouldNotStore or SuppressStore) to CacheEntry, with a public setter on ICacheEntry.
  • Update the relevant cache entry creation extension methods (GetOrCreateAsync, GetOrCreate, etc.) in MemoryCacheExtensions.cs to check this property after the factory executes. If the flag is set, do not store the entry in the cache.
  • Update the cache logic to ensure that if the flag is set, the entry is not added, and no value is cached.
  • Add appropriate tests to verify that when the new flag is set, values are not cached and subsequent calls recompute the result.

References to update:

  • src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntry.cs
  • src/libraries/Microsoft.Extensions.Caching.Abstractions/src/MemoryCacheExtensions.cs
  • Add/modify tests in src/libraries/Microsoft.Extensions.Caching.Memory/tests/MemoryCacheSetAndRemoveTests.cs

This pull request was created as a result of the following prompt from Copilot chat.

Add a flag to CacheEntry (in Microsoft.Extensions.Caching.Memory) that indicates whether the result computed by GetOrCreateAsync, GetOrCreate, and similar cache entry creation methods should be stored in the cache. If, during processing in the factory method, a condition arises that means the cache entry should not be used, this flag can be set, and the entry will not be stored (so subsequent requests will re-execute the factory).

Implementation details:

  • Add a boolean property (e.g., ShouldNotStore or SuppressStore) to CacheEntry, with a public setter on ICacheEntry.
  • Update the relevant cache entry creation extension methods (GetOrCreateAsync, GetOrCreate, etc.) in MemoryCacheExtensions.cs to check this property after the factory executes. If the flag is set, do not store the entry in the cache.
  • Update the cache logic to ensure that if the flag is set, the entry is not added, and no value is cached.
  • Add appropriate tests to verify that when the new flag is set, values are not cached and subsequent calls recompute the result.

References to update:

  • src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntry.cs
  • src/libraries/Microsoft.Extensions.Caching.Abstractions/src/MemoryCacheExtensions.cs
  • Add/modify tests in src/libraries/Microsoft.Extensions.Caching.Memory/tests/MemoryCacheSetAndRemoveTests.cs

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Co-authored-by: mitchdenny <513398+mitchdenny@users.noreply.github.com>
@Copilot Copilot AI changed the title [WIP] Add flag to CacheEntry for suppressing cache storage Add ShouldNotStore flag to ICacheEntry for conditional cache suppression Oct 21, 2025
@Copilot Copilot AI requested a review from mitchdenny October 21, 2025 10:51
Copilot finished work on behalf of mitchdenny October 21, 2025 10:51
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-extensions-caching
See info in area-owners.md if you want to be subscribed.

System.Collections.Generic.IList<Microsoft.Extensions.Caching.Memory.PostEvictionCallbackRegistration> PostEvictionCallbacks { get; }
Microsoft.Extensions.Caching.Memory.CacheItemPriority Priority { get; set; }
long? Size { get; set; }
bool ShouldNotStore { get; set; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is adding new public API. It needs an approved API proposal first

https://github.com/dotnet/runtime/blob/main/docs/project/api-review-process.md

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. Just spiking out and experimenting at the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants