-
Notifications
You must be signed in to change notification settings - Fork 812
HybridCache : simplify AOT usage with default JSON serialization #6475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -12,6 +12,9 @@ | |||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
namespace Microsoft.Extensions.Caching.Hybrid.Internal; | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
[UnconditionalSuppressMessage("AOT", "IL2026", Justification = "Checked at runtime, guidance issued")] | ||||||||||||||||||||||||||||||||||||
[UnconditionalSuppressMessage("AOT", "IL2070", Justification = "Checked at runtime, guidance issued")] | ||||||||||||||||||||||||||||||||||||
[UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Checked at runtime, guidance issued")] | ||||||||||||||||||||||||||||||||||||
Comment on lines
+15
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These should be moved even more local to only suppress around the lines of code that need it. Doing it the current way will suppress it for all new code written in this class, which isn't correct. Also, is there a better Justifcation that can be written here? A little more of a reason why this is OK. See
for some examples. |
||||||||||||||||||||||||||||||||||||
internal sealed class DefaultJsonSerializerFactory : IHybridCacheSerializerFactory | ||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||
private readonly IServiceProvider _serviceProvider; | ||||||||||||||||||||||||||||||||||||
|
@@ -34,7 +37,7 @@ public bool TryCreateSerializer<T>([NotNullWhen(true)] out IHybridCacheSerialize | |||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// see if there is a per-type options registered (keyed by the **closed** generic type), otherwise use the default | ||||||||||||||||||||||||||||||||||||
JsonSerializerOptions options = _serviceProvider.GetKeyedService<JsonSerializerOptions>(typeof(IHybridCacheSerializer<T>)) ?? Options; | ||||||||||||||||||||||||||||||||||||
eerhardt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||
if (!options.IncludeFields && ReferenceEquals(options, SystemDefaultJsonOptions) && IsFieldOnlyType(typeof(T))) | ||||||||||||||||||||||||||||||||||||
if (!options.IncludeFields && IsDefaultJsonOptions(options) && IsFieldOnlyType(typeof(T))) | ||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||
// value-tuples expose fields, not properties; special-case this as a common scenario | ||||||||||||||||||||||||||||||||||||
options = FieldEnabledJsonOptions; | ||||||||||||||||||||||||||||||||||||
|
@@ -50,11 +53,38 @@ internal static bool IsFieldOnlyType(Type type) | |||||||||||||||||||||||||||||||||||
return IsFieldOnlyType(type, ref state) == FieldOnlyResult.FieldOnly; | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
private static bool IsDefaultJsonOptions(JsonSerializerOptions options) | ||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||
if (!JsonSerializer.IsReflectionEnabledByDefault) | ||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||
// can't be, since we don't use default options for AOT | ||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
#pragma warning disable IDE0079 // unnecessary suppression: TFM-dependent | ||||||||||||||||||||||||||||||||||||
#pragma warning disable IL2026, IL3050 // AOT bits | ||||||||||||||||||||||||||||||||||||
private static JsonSerializerOptions SystemDefaultJsonOptions => JsonSerializerOptions.Default; | ||||||||||||||||||||||||||||||||||||
return ReferenceEquals(options, JsonSerializerOptions.Default); | ||||||||||||||||||||||||||||||||||||
#pragma warning restore IL2026, IL3050 | ||||||||||||||||||||||||||||||||||||
#pragma warning restore IDE0079 | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
private static JsonSerializerOptions SystemDefaultJsonOptions | ||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||
get | ||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||
if (!JsonSerializer.IsReflectionEnabledByDefault) | ||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||
throw new NotSupportedException($"When using AOT, {nameof(JsonSerializerOptions)} with {nameof(JsonSerializerOptions.TypeInfoResolver)} specified must be provided via" | ||||||||||||||||||||||||||||||||||||
+ $" {nameof(IHybridCacheBuilder)}.{nameof(HybridCacheBuilderExtensions.WithJsonSerializerOptions)}."); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
#pragma warning disable IDE0079 // unnecessary suppression: TFM-dependent | ||||||||||||||||||||||||||||||||||||
#pragma warning disable IL2026, IL3050 // AOT bits | ||||||||||||||||||||||||||||||||||||
return JsonSerializerOptions.Default; | ||||||||||||||||||||||||||||||||||||
#pragma warning restore IL2026, IL3050 | ||||||||||||||||||||||||||||||||||||
#pragma warning restore IDE0079 | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
[SuppressMessage("Trimming", "IL2070:'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.", | ||||||||||||||||||||||||||||||||||||
Justification = "Custom serializers may be needed for AOT with STJ")] | ||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -23,6 +23,11 @@ | |||||||||||||
<DisableMicrosoftExtensionsLoggingSourceGenerator>false</DisableMicrosoftExtensionsLoggingSourceGenerator> | ||||||||||||||
</PropertyGroup> | ||||||||||||||
|
||||||||||||||
<PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))"> | ||||||||||||||
<IsTrimmable>true</IsTrimmable> | ||||||||||||||
<IsAotCompatible>true</IsAotCompatible> | ||||||||||||||
Comment on lines
24
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
You only need to set |
||||||||||||||
</PropertyGroup> | ||||||||||||||
|
||||||||||||||
<PropertyGroup> | ||||||||||||||
<Stage>normal</Stage> | ||||||||||||||
<MinCodeCoverage>82</MinCodeCoverage> | ||||||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.