extensions icon indicating copy to clipboard operation
extensions copied to clipboard

HybridCache : simplify AOT usage with default JSON serialization

Open mgravell opened this issue 7 months ago • 9 comments

  1. don't touch JsonSerializerOptions.Default in AOT mode
  2. add new extension methods to register JsonSerializerOptions (these are convenience methods on an existing registration pattern)
  3. offer a suitable runtime error message instead, if no JSON options supplied in AOT mode
  4. include [UnconditionalSuppressMessage] to prevent build-time consumer warnings

This has been tested successfully with an AOT published project; it now works correctly at runtime with zero build-time warnings, test code shown below; without the WithJsonSerializerOptions line, exception at runtime:

When using AOT, JsonSerializerOptions with TypeInfoResolver specified must be provided via IHybridCacheBuilder.WithJsonSerializerOptions.

Without this work, it is not obvious how to register AOT JSON options, and the consumer must use <NoWarn>$(NoWarn);IL2026;IL2104;IL3053</NoWarn> or similar to get a clean build, which is too wide.

open questions:

  • API naming: With* or Add* ?
  • which API review process should this follow?

Sample:

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Extensions.Caching.Hybrid;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
var jsonOptions = new JsonSerializerOptions() { TypeInfoResolver = Bar.MyJsonSerializationContext.Default };
services.AddHybridCache().WithJsonSerializerOptions(jsonOptions);
services.AddStackExchangeRedisCache(options => options.Configuration = "localhost:6379");
using var provider = services.BuildServiceProvider();

var cache = provider.GetRequiredService<HybridCache>();

int id = 42;
var obj = await cache.GetOrCreateAsync($"/ob/{id}", ct => GetTheThingAsync(id));
Console.WriteLine(obj.Id);

static ValueTask<Bar.Foo> GetTheThingAsync(int id) => new(new Bar.Foo(id));

namespace Bar
{
    [JsonSourceGenerationOptions(WriteIndented = true)]
    [JsonSerializable(typeof(Foo))]
    internal partial class MyJsonSerializationContext : JsonSerializerContext
    {
    }

    internal sealed class Foo(int id)
    {
        public int Id => id;
    }
}
Microsoft Reviewers: Open in CodeFlow

mgravell avatar May 21 '25 10:05 mgravell

CI build fail is because of API delta:

error LA0003: (NETCORE_ENGINEERING_TELEMETRY=Build) Newly added symbol 'Microsoft.Extensions.DependencyInjection.HybridCacheBuilderExtensions.WithJsonSerializerOptions(Microsoft.Extensions.Caching.Hybrid.IHybridCacheBuilder, System.Text.Json.JsonSerializerOptions)' must be marked as experimental

This in in turn tied into the open "which API review process should this follow?" question; however, I'll add the attribute for now

mgravell avatar May 21 '25 11:05 mgravell

We should remove

https://github.com/dotnet/extensions/blob/6f29ab505709370fc9b72bf4bb7e004a7662f69f/test/Libraries/Microsoft.Extensions.AotCompatibility.TestApp/Microsoft.Extensions.AotCompatibility.TestApp.csproj#L20-L21

as well. We should make the library trimming and AOT compatible.

eerhardt avatar May 21 '25 22:05 eerhardt

@eerhardt @sebastienros maybe assign a different person? (maybe one that still is employed by MS, heck why not give copilot a shot at it?)

KLuuKer avatar Nov 23 '25 06:11 KLuuKer

sebastienros unassigned mgravell 3 hours ago

dotnet-policy-service dotnet-policy-service bot assigned mgravell 3 hours ago

🎵 Welcome to the repo California... 🎶 you can checkout any time you like, but you can never leave

mgravell avatar Nov 24 '25 21:11 mgravell

@mgravell I think you need to delete this account and create a new one

sebastienros avatar Nov 24 '25 21:11 sebastienros

(deletes dotnet, as requested)

mjgaux avatar Nov 24 '25 22:11 mjgaux

(considers reporting dotnet-policy-service for... harassment? TOS violations? just "being a total jerk"?)

mgravell avatar Nov 25 '25 18:11 mgravell

FYI we hoped this PR would fix it

sebastienros avatar Nov 25 '25 18:11 sebastienros