fix: add an implementation for saving primitive data

This commit is contained in:
Polianin Nikita 2024-10-31 04:05:40 +03:00
parent 5317b7b563
commit 5bc729eb66
2 changed files with 60 additions and 5 deletions

View File

@ -17,12 +17,43 @@ public class DistributedCacheService(IDistributedCache cache) : ICacheService
SlidingExpiration = slidingExpiration SlidingExpiration = slidingExpiration
}; };
var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
if (type.IsPrimitive || type == typeof(string) || type == typeof(DateTime))
{
await cache.SetStringAsync(key, value?.ToString() ?? string.Empty, options, cancellationToken);
return;
}
var serializedValue = value as byte[] ?? JsonSerializer.SerializeToUtf8Bytes(value); var serializedValue = value as byte[] ?? JsonSerializer.SerializeToUtf8Bytes(value);
await cache.SetAsync(key, serializedValue, options, cancellationToken); await cache.SetAsync(key, serializedValue, options, cancellationToken);
} }
public async Task<T?> GetAsync<T>(string key, CancellationToken cancellationToken = default) public async Task<T?> GetAsync<T>(string key, CancellationToken cancellationToken = default)
{ {
var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
if (type.IsPrimitive || type == typeof(string) || type == typeof(DateTime))
{
var primitiveValue = await cache.GetStringAsync(key, cancellationToken);
if (string.IsNullOrEmpty(primitiveValue))
return default;
if (type == typeof(string))
return (T?)(object?)primitiveValue;
var tryParseMethod = type.GetMethod("TryParse", [typeof(string), type.MakeByRefType()])
?? throw new NotSupportedException($"Type {type.Name} does not support TryParse.");
var parameters = new[] { primitiveValue, Activator.CreateInstance(type) };
var success = (bool)tryParseMethod.Invoke(null, parameters)!;
if (success)
return (T)parameters[1]!;
return default;
}
var cachedValue = await cache.GetAsync(key, cancellationToken); var cachedValue = await cache.GetAsync(key, cancellationToken);
return cachedValue == null ? default : JsonSerializer.Deserialize<T>(cachedValue); return cachedValue == null ? default : JsonSerializer.Deserialize<T>(cachedValue);
} }

View File

@ -17,17 +17,41 @@ public class MemoryCacheService(IMemoryCache cache) : ICacheService
SlidingExpiration = slidingExpiration SlidingExpiration = slidingExpiration
}; };
var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
if (type.IsPrimitive || type == typeof(string) || type == typeof(DateTime))
{
cache.Set(key, value?.ToString() ?? string.Empty, options);
return Task.CompletedTask;
}
cache.Set(key, value as byte[] ?? JsonSerializer.SerializeToUtf8Bytes(value), options); cache.Set(key, value as byte[] ?? JsonSerializer.SerializeToUtf8Bytes(value), options);
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task<T?> GetAsync<T>(string key, CancellationToken cancellationToken = default) public Task<T?> GetAsync<T>(string key, CancellationToken cancellationToken = default)
{ {
var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
if (!type.IsPrimitive && type != typeof(string) && type != typeof(DateTime))
return Task.FromResult( return Task.FromResult(
cache.TryGetValue(key, out byte[]? value) ? cache.TryGetValue(key, out byte[]? value) ? JsonSerializer.Deserialize<T>(value) : default
JsonSerializer.Deserialize<T>(value) :
default
); );
var primitiveValue = cache.Get(key);
if (string.IsNullOrEmpty(primitiveValue?.ToString()))
return Task.FromResult<T?>(default);
if (type == typeof(string))
return Task.FromResult((T?)primitiveValue);
var tryParseMethod = type.GetMethod("TryParse", [typeof(string), type.MakeByRefType()])
?? throw new NotSupportedException($"Type {type.Name} does not support TryParse.");
var parameters = new[] { primitiveValue, Activator.CreateInstance(type) };
var success = (bool)tryParseMethod.Invoke(null, parameters)!;
return success ? Task.FromResult((T?)parameters[1]) : Task.FromResult<T?>(default);
} }
public Task RemoveAsync(string key, CancellationToken cancellationToken = default) public Task RemoveAsync(string key, CancellationToken cancellationToken = default)