Skip to content

Commit

Permalink
feat: allow for specifying custom json serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobAtchley committed Jul 8, 2024
1 parent 1e32d38 commit 90123e6
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 8 deletions.
10 changes: 10 additions & 0 deletions LitRedis.Core/Builders/LitRedisServiceCollectionBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Text.Json;
using LitRedis.Core.Implementations;
using LitRedis.Core.Interfaces;
using LitRedis.Core.Models;
Expand All @@ -11,11 +12,14 @@ public class LitRedisServiceCollectionBuilder
{
public IServiceCollection ServiceCollection { get; }
private readonly LitRedisOptions _litRedisOptions = new();
private readonly JsonSerializerOptions _jsonOptions = new(JsonSerializerDefaults.Web);

public LitRedisServiceCollectionBuilder(IServiceCollection serviceCollection)
{
ServiceCollection = serviceCollection;

serviceCollection.TryAddSingleton(_litRedisOptions);
serviceCollection.TryAddSingleton<ILitRedisSystemTextJsonOptionsProvider>(new DefaultLitRedisSystemTextJsonOptionsProvider(_jsonOptions));
serviceCollection.TryAddSingleton<ILitRedisConnection, LitLitRedisConnection>();
serviceCollection.TryAddScoped<ILitRedisConnectionService, LitRedisConnectionService>();
}
Expand Down Expand Up @@ -43,4 +47,10 @@ public LitRedisServiceCollectionBuilder WithLitRedisOptions(Action<LitRedisOptio
configure(_litRedisOptions);
return this;
}

public LitRedisServiceCollectionBuilder WithJsonOptions(Action<JsonSerializerOptions> configure)
{
configure(_jsonOptions);
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Text.Json;
using LitRedis.Core.Interfaces;

namespace LitRedis.Core.Implementations;

public class DefaultLitRedisSystemTextJsonOptionsProvider(JsonSerializerOptions options)
: ILitRedisSystemTextJsonOptionsProvider
{
public JsonSerializerOptions GetOptions() => options;
}
13 changes: 8 additions & 5 deletions LitRedis.Core/Implementations/LitRedisCacheStore.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using LitRedis.Core.Interfaces;
Expand All @@ -14,11 +13,15 @@ public class LitRedisCacheStore : ILitRedisCacheStore
{
private readonly IMemoryCache _cache;
private readonly ILitRedisConnectionService _litRedisConnectionService;
private readonly ILitRedisJsonSerializer _jsonSerializer;

public LitRedisCacheStore(IMemoryCache cache, ILitRedisConnectionService litRedisConnectionService)
public LitRedisCacheStore(IMemoryCache cache,
ILitRedisConnectionService litRedisConnectionService,
ILitRedisJsonSerializer jsonSerializer)
{
_cache = cache;
_litRedisConnectionService = litRedisConnectionService;
_jsonSerializer = jsonSerializer;
}

private static void KeyGuard(string key)
Expand All @@ -43,9 +46,9 @@ public async Task PutAsync<T>(string key, T model, TimeSpan? expiry, Cancellatio
return;
}

var str = JsonSerializer.Serialize(model);
var json = _jsonSerializer.Serialize(model);

await _litRedisConnectionService.UseDbAsync((db, _) => db.StringSetAsync(key, str, expiry), cancellationToken);
await _litRedisConnectionService.UseDbAsync((db, _) => db.StringSetAsync(key, json, expiry), cancellationToken);
}

/// <inheritdoc />
Expand All @@ -57,7 +60,7 @@ public async Task<T> GetAsync<T>(string key, CancellationToken cancellationToken

var str = await GetAsync(key, cancellationToken);

return string.IsNullOrWhiteSpace(str) ? default : JsonSerializer.Deserialize<T>(str);
return string.IsNullOrWhiteSpace(str) ? default : _jsonSerializer.Deserialize<T>(str);
}

/// <inheritdoc />
Expand Down
18 changes: 18 additions & 0 deletions LitRedis.Core/Implementations/LitRedisSystemTextJsonSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Text.Json;
using LitRedis.Core.Interfaces;

namespace LitRedis.Core.Implementations;

public class LitRedisSystemTextJsonSerializer : ILitRedisJsonSerializer
{
private readonly ILitRedisSystemTextJsonOptionsProvider _optionsProvider;

public LitRedisSystemTextJsonSerializer(ILitRedisSystemTextJsonOptionsProvider optionsProvider)
{
_optionsProvider = optionsProvider;
}

public string Serialize<T>(T value) => JsonSerializer.Serialize(value, _optionsProvider.GetOptions());

public T Deserialize<T>(string value) => JsonSerializer.Deserialize<T>(value, _optionsProvider.GetOptions());
}
8 changes: 8 additions & 0 deletions LitRedis.Core/Interfaces/ILitRedisJsonSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace LitRedis.Core.Interfaces;

public interface ILitRedisJsonSerializer
{
string Serialize<T>(T value);

T Deserialize<T>(string value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Text.Json;

namespace LitRedis.Core.Interfaces;

public interface ILitRedisSystemTextJsonOptionsProvider
{
JsonSerializerOptions GetOptions();
}
2 changes: 1 addition & 1 deletion LitRedis.Core/LitRedis.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Version>4.0.3</Version>
<Version>4.0.4</Version>
<LangVersion>latestmajor</LangVersion>
</PropertyGroup>

Expand Down
3 changes: 2 additions & 1 deletion LitRedis.Core/ServiceProviderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ namespace LitRedis.Core;
//todo: test
public static class ServiceProviderExtensions
{
public static IServiceCollection AddLitRedis(this IServiceCollection serviceCollection,
public static IServiceCollection AddLitRedis(
this IServiceCollection serviceCollection,
Action<LitRedisServiceCollectionBuilder> configure)
{
var builder = new LitRedisServiceCollectionBuilder(serviceCollection);
Expand Down
5 changes: 4 additions & 1 deletion LitRedis.Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ private static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefau
.ConfigureServices((_, services) =>
{
services
.AddLitRedis(redis => redis.WithCaching().WithLocking().WithConnectionString("localhost:6379,defaultDatabase=0"))
.AddLitRedis(redis => redis
.WithCaching()
.WithLocking()
.WithConnectionString("localhost:6379,defaultDatabase=0"))
.AddHostedService<SampleHostedService>()
.AddLogging(o => o.AddSimpleConsole(c => c.TimestampFormat = "[yyy-MM-dd HH:mm:ss] "));
});
Expand Down
47 changes: 47 additions & 0 deletions LitRedis.Tests/Core/Implementations/JsonSerializationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.Drawing;
using System.Dynamic;
using System.Text.Json;
using FluentAssertions;
using LitRedis.Core.Builders;
using LitRedis.Core.Interfaces;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace LitRedis.Tests.Core.Implementations;

class SampleClass

Check warning on line 12 in LitRedis.Tests/Core/Implementations/JsonSerializationTests.cs

View workflow job for this annotation

GitHub Actions / Build and test

Accessibility modifiers required
{
public string Name { get; set; }
public int Age { get; set; }
public ExpandoObject Custom { get; set; }
}

[TestClass]
public class JsonSerializationTests
{
[TestMethod]
public void Json_Serializer_Should_Handle_Expando()
{
dynamic custom = new ExpandoObject();
custom.Color = "Red";
custom.Size = "Large";

var sample = new SampleClass
{
Name = "John Doe",
Age = 30,
Custom = custom
};

var sp = new LitRedisServiceCollectionBuilder(new ServiceCollection()).ServiceCollection.BuildServiceProvider();
var options = sp.GetRequiredService<ILitRedisSystemTextJsonOptionsProvider>().GetOptions();
var serialized = JsonSerializer.Serialize(sample, options);
var deserialized = JsonSerializer.Deserialize<SampleClass>(serialized, options);
var serializedAgain = JsonSerializer.Serialize(deserialized, options);
serializedAgain.Should()
.Be("{\"name\":\"John Doe\",\"age\":30,\"custom\":{\"Color\":\"Red\",\"Size\":\"Large\"}}");
dynamic c = deserialized.Custom;
string color = c.Color.ToString();
color.Should().Be("Red");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public async Task Lit_Redis_Cache_Store_Should_Get_Value_Object()

var mockRedisConnectionService = fixture.Freeze<Mock<ILitRedisConnectionService>>();

fixture.Inject<ILitRedisJsonSerializer>(new LitRedisSystemTextJsonSerializer(new DefaultLitRedisSystemTextJsonOptionsProvider(new JsonSerializerOptions(JsonSerializerDefaults.Web))));

mockRedisConnectionService.Setup(x =>
x.UseDbAsync(It.IsAny<Func<IDatabase, CancellationToken, Task<RedisValue>>>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new RedisValue(JsonSerializer.Serialize(cacheValue)));
Expand Down

0 comments on commit 90123e6

Please sign in to comment.