-
Notifications
You must be signed in to change notification settings - Fork 4.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Provide a configurable overload of MemoryCacheEntryOptions for the commonly used method GetOrCreate in MemoryCacheExtension #92101
Comments
Tagging subscribers to this area: @dotnet/area-extensions-caching Issue DetailsBackground and motivationIn the MemoryCache extension class, The commonly used GetOrCreateAsync() should have an overloaded method for setting the MemoryCacheEntryOptions property API Proposalnamespace System.Collections.Generic;
public class MemoryCacheExtensions
{
/// <summary>
/// Gets the value associated with this key if it exists, or generates a new entry using the provided key and a value from the given factory if the key is not found.
/// </summary>
/// <typeparam name="TItem">The type of the object to get.</typeparam>
/// <param name="cache">The <see cref="IMemoryCache"/> instance this method extends.</param>
/// <param name="key">The key of the entry to look for or create.</param>
/// <param name="factory">The factory that creates the value associated with this key if the key does not exist in the cache.</param>
/// <param name="options">The existing <see cref="MemoryCacheEntryOptions"/> instance to apply to the new entry.</param>
/// <returns>The value associated with this key.</returns>
public static TItem? GetOrCreate<TItem>(this IMemoryCache cache, object key, Func<ICacheEntry, TItem> factory, MemoryCacheEntryOptions? options)
{
if (!cache.TryGetValue(key, out object? result))
{
using ICacheEntry entry = cache.CreateEntry(key);
if (options != null) {
entry.SetOptions(options);
}
result = factory(entry);
entry.Value = result;
}
return (TItem?)result;
}
/// <summary>
/// Asynchronously gets the value associated with this key if it exists, or generates a new entry using the provided key and a value from the given factory if the key is not found.
/// </summary>
/// <typeparam name="TItem">The type of the object to get.</typeparam>
/// <param name="cache">The <see cref="IMemoryCache"/> instance this method extends.</param>
/// <param name="key">The key of the entry to look for or create.</param>
/// <param name="factory">The factory task that creates the value associated with this key if the key does not exist in the cache.</param>
/// <param name="options">The existing <see cref="MemoryCacheEntryOptions"/> instance to apply to the new entry.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
public static async Task<TItem?> GetOrCreateAsync<TItem>(this IMemoryCache cache, object key, Func<ICacheEntry, Task<TItem>> factory, MemoryCacheEntryOptions? options)
{
if (!cache.TryGetValue(key, out object? result))
{
using ICacheEntry entry = cache.CreateEntry(key);
if (options != null) {
entry.SetOptions(options);
}
result = await factory(entry).ConfigureAwait(false);
entry.Value = result;
}
return (TItem?)result;
}
} API Usage// GetOrCreateAsync And Set MemoryCacheEntryOptions
var key = _cache.GetOrCreate("yj-key", c => "key-value", new MemoryCacheEntryOptions()
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1)
});
var key = await _cache.GetOrCreateAsync("yj-key", c => "key-value", new MemoryCacheEntryOptions()
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1)
}); Alternative DesignsYou can change the existing GetOrCreate method, add parameters, and set default values to avoid destructive updates, but relatively speaking, overloading a new method is more suitable RisksThe code generated by the change is all existing code within the extension method, and no new logical code has been generated, resulting in a low risk factor. But we still need to consider whether the execution order of SetOptions within the method in the above example code will have an impact on the functionality.
|
It sounds reasonable, I am supportive of this proposal. Let's discuss it at API Review meeting. |
namespace Microsoft.Extensions.Caching.Memory;
public partial class CacheExtensions
{
public static TItem? GetOrCreate<TItem>(
this IMemoryCache cache,
object key,
Func<ICacheEntry, TItem> factory,
MemoryCacheEntryOptions? createOptions);
public static async Task<TItem?> GetOrCreateAsync<TItem>(
this IMemoryCache cache,
object key,
Func<ICacheEntry, Task<TItem>> factory,
MemoryCacheEntryOptions? createOptions);
} |
I've applied "help wanted" label, which means that we would be more than happy to review a community PR that adds these two new methods. Some hints:
.\dotnet.cmd build .\src\libraries\Microsoft.Extensions.Caching.Abstractions\Microsoft.Extensions.Caching.Abstractions.sln
&& .\dotnet.cmd build .\src\libraries\Microsoft.Extensions.Caching.Memory\tests\Microsoft.Extensions.Caching.Memory.Tests.csproj /t:Test |
@adamsitnik could I take this one, and thank you very much for the detailed hints |
Yes, of course! I've assigned you, please let me know if you need any help. |
@git102347501 would you like to take this since you had drafted a PR before? |
No problem,Thank |
Background and motivation
In the MemoryCache extension class, The commonly used GetOrCreateAsync() should have an overloaded method for setting the MemoryCacheEntryOptions property
When we use the caching function. It is usually necessary to set MemoryCacheEntryOptions to determine the cache timeout and other configuration properties. If GetOrCreate does not provide an overload of valid MemoryCacheEntryOptions, this method will become unavailable in the scenario where MemoryCacheEntryOptions need to be configured. Users can only go back and select Get and call the Set method to configure.
API Proposal
API Usage
Alternative Designs
You can change the existing GetOrCreate method, add parameters, and set default values to avoid destructive updates, but relatively speaking, overloading a new method is more suitable
Risks
The code generated by the change is all existing code within the extension method, and no new logical code has been generated, resulting in a low risk factor.
But we still need to consider whether the execution order of SetOptions within the method in the above example code will have an impact on the functionality.
The text was updated successfully, but these errors were encountered: