Add GetOrAddAsync to DistributedCache.

pull/395/head
Halil ibrahim Kalkan 7 years ago
parent 2d8d2075cd
commit 250f2d1f8a

@ -3,6 +3,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Nito.AsyncEx;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Serialization;
using Volo.Abp.Threading;
@ -24,10 +25,12 @@ namespace Volo.Abp.Caching
protected ICurrentTenant CurrentTenant { get; }
protected AsyncLock AsyncLock { get; } = new AsyncLock();
public DistributedCache(
IDistributedCache cache,
ICancellationTokenProvider cancellationTokenProvider,
IObjectSerializer objectSerializer,
IObjectSerializer objectSerializer,
ICurrentTenant currentTenant)
{
Cache = cache;
@ -60,6 +63,53 @@ namespace Volo.Abp.Caching
return ObjectSerializer.Deserialize<TCacheItem>(cachedBytes);
}
public TCacheItem GetOrAdd(string key, Func<TCacheItem> factory)
{
var value = Get(key);
if (value != null)
{
return value;
}
using (AsyncLock.Lock())
{
value = Get(key);
if (value != null)
{
return value;
}
value = factory();
Set(key, value);
}
return value;
}
public async Task<TCacheItem> GetOrAddAsync(string key, Func<Task<TCacheItem>> factory, CancellationToken token = default)
{
var value = await GetAsync(key, token);
if (value != null)
{
return value;
}
using (await AsyncLock.LockAsync(token))
{
value = await GetAsync(key, token);
if (value != null)
{
return value;
}
value = await factory();
await SetAsync(key, value, token: token);
}
return value;
}
public virtual void Set(string key, TCacheItem value, DistributedCacheEntryOptions options = null)
{
Cache.Set(

@ -1,4 +1,5 @@
using System.Threading;
using System;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Caching.Distributed;
@ -17,6 +18,17 @@ namespace Volo.Abp.Caching
CancellationToken token = default
);
TCacheItem GetOrAdd(
string key,
Func<TCacheItem> factory
);
Task<TCacheItem> GetOrAddAsync(
[NotNull] string key,
Func<Task<TCacheItem>> factory,
CancellationToken token = default
);
void Set(
string key,
TCacheItem value,

@ -3,6 +3,7 @@ using JetBrains.Annotations;
namespace Volo.Abp.Localization
{
[Serializable]
public class LanguageInfo
{
[NotNull]
@ -17,6 +18,11 @@ namespace Volo.Abp.Localization
[CanBeNull]
public virtual string FlagIcon { get; set; }
protected LanguageInfo()
{
}
public LanguageInfo(
string cultureName,
string uiCultureName = null,

@ -35,5 +35,42 @@ namespace Volo.Abp.Caching
cacheItem = await personCache.GetAsync(cacheKey);
cacheItem.ShouldBeNull();
}
[Fact]
public async Task GetOrAddAsync()
{
var personCache = GetRequiredService<IDistributedCache<PersonCacheItem>>();
var cacheKey = Guid.NewGuid().ToString();
const string personName = "john nash";
//Will execute the factory method to create the cache item
bool factoryExecuted = false;
var cacheItem = await personCache.GetOrAddAsync(cacheKey,
async () =>
{
factoryExecuted = true;
return new PersonCacheItem(personName);
});
factoryExecuted.ShouldBeTrue();
cacheItem.Name.ShouldBe(personName);
//This time, it will not execute the factory
factoryExecuted = false;
cacheItem = await personCache.GetOrAddAsync(cacheKey,
async () =>
{
factoryExecuted = true;
return new PersonCacheItem(personName);
});
factoryExecuted.ShouldBeFalse();
cacheItem.Name.ShouldBe(personName);
}
}
}

Loading…
Cancel
Save