Browse Source

Add GetOrAddAsync to DistributedCache.

pull/395/head
Halil ibrahim Kalkan 8 years ago
parent
commit
250f2d1f8a
  1. 52
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs
  2. 14
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs
  3. 6
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfo.cs
  4. 37
      framework/test/Volo.Abp.Caching.Tests/Volo/Abp/Caching/DistributedCache_Tests.cs

52
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs

@ -3,6 +3,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using Nito.AsyncEx;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.Serialization; using Volo.Abp.Serialization;
using Volo.Abp.Threading; using Volo.Abp.Threading;
@ -24,10 +25,12 @@ namespace Volo.Abp.Caching
protected ICurrentTenant CurrentTenant { get; } protected ICurrentTenant CurrentTenant { get; }
protected AsyncLock AsyncLock { get; } = new AsyncLock();
public DistributedCache( public DistributedCache(
IDistributedCache cache, IDistributedCache cache,
ICancellationTokenProvider cancellationTokenProvider, ICancellationTokenProvider cancellationTokenProvider,
IObjectSerializer objectSerializer, IObjectSerializer objectSerializer,
ICurrentTenant currentTenant) ICurrentTenant currentTenant)
{ {
Cache = cache; Cache = cache;
@ -60,6 +63,53 @@ namespace Volo.Abp.Caching
return ObjectSerializer.Deserialize<TCacheItem>(cachedBytes); 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) public virtual void Set(string key, TCacheItem value, DistributedCacheEntryOptions options = null)
{ {
Cache.Set( Cache.Set(

14
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs

@ -1,4 +1,5 @@
using System.Threading; using System;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
@ -17,6 +18,17 @@ namespace Volo.Abp.Caching
CancellationToken token = default 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( void Set(
string key, string key,
TCacheItem value, TCacheItem value,

6
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfo.cs

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

37
framework/test/Volo.Abp.Caching.Tests/Volo/Abp/Caching/DistributedCache_Tests.cs

@ -35,5 +35,42 @@ namespace Volo.Abp.Caching
cacheItem = await personCache.GetAsync(cacheKey); cacheItem = await personCache.GetAsync(cacheKey);
cacheItem.ShouldBeNull(); 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