|
8 | 8 |
|
9 | 9 | namespace System.Text.Json.Serialization.Metadata
|
10 | 10 | {
|
11 |
| - [RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)] |
12 | 11 | internal sealed partial class ReflectionEmitCachingMemberAccessor : MemberAccessor
|
13 | 12 | {
|
14 |
| - private static readonly ReflectionEmitMemberAccessor s_sourceAccessor = new(); |
15 |
| - private static readonly Cache<(string id, Type declaringType, MemberInfo? member)> s_cache = |
16 |
| - new(slidingExpiration: TimeSpan.FromMilliseconds(1000), evictionInterval: TimeSpan.FromMilliseconds(200)); |
| 13 | + private readonly ReflectionEmitMemberAccessor _sourceAccessor; |
| 14 | + private readonly Cache<(string id, Type declaringType, MemberInfo? member)> _cache; |
17 | 15 |
|
18 |
| - public static void Clear() => s_cache.Clear(); |
| 16 | + [RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)] |
| 17 | + [RequiresUnreferencedCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)] |
| 18 | + public ReflectionEmitCachingMemberAccessor() |
| 19 | + { |
| 20 | + _sourceAccessor = new ReflectionEmitMemberAccessor(); |
| 21 | + _cache = new(slidingExpiration: TimeSpan.FromMilliseconds(1000), evictionInterval: TimeSpan.FromMilliseconds(200)); |
| 22 | + } |
19 | 23 |
|
20 |
| - public override Action<TCollection, object?> CreateAddMethodDelegate<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TCollection>() |
21 |
| - => s_cache.GetOrAdd((nameof(CreateAddMethodDelegate), typeof(TCollection), null), |
22 |
| - static (_) => s_sourceAccessor.CreateAddMethodDelegate<TCollection>()); |
| 24 | + public override void Clear() => _cache.Clear(); |
23 | 25 |
|
24 |
| - public override Func<object>? CreateParameterlessConstructor([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type, ConstructorInfo? ctorInfo) |
25 |
| - => s_cache.GetOrAdd((nameof(CreateParameterlessConstructor), type, ctorInfo), |
26 |
| - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2077:UnrecognizedReflectionPattern", |
27 |
| - Justification = "Cannot apply DynamicallyAccessedMembersAttribute to tuple properties.")] |
28 |
| -#pragma warning disable IL2077 // The suppression doesn't work for the trim analyzer: https://github.com/dotnet/roslyn/issues/59746 |
29 |
| - static (key) => s_sourceAccessor.CreateParameterlessConstructor(key.declaringType, (ConstructorInfo?)key.member)); |
30 |
| -#pragma warning restore IL2077 |
| 26 | + public override Action<TCollection, object?> CreateAddMethodDelegate<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TCollection>() => |
| 27 | + _cache.GetOrAdd( |
| 28 | + key: (nameof(CreateAddMethodDelegate), typeof(TCollection), null), |
| 29 | + _ => _sourceAccessor.CreateAddMethodDelegate<TCollection>()); |
31 | 30 |
|
32 |
| - public override Func<object, TProperty> CreateFieldGetter<TProperty>(FieldInfo fieldInfo) |
33 |
| - => s_cache.GetOrAdd((nameof(CreateFieldGetter), typeof(TProperty), fieldInfo), static key => s_sourceAccessor.CreateFieldGetter<TProperty>((FieldInfo)key.member!)); |
| 31 | + public override Func<object>? CreateParameterlessConstructor(Type type, ConstructorInfo? ctorInfo) => |
| 32 | + _cache.GetOrAdd( |
| 33 | + key: (nameof(CreateParameterlessConstructor), type, ctorInfo), |
| 34 | + valueFactory: key => _sourceAccessor.CreateParameterlessConstructor(key.declaringType, (ConstructorInfo?)key.member)); |
34 | 35 |
|
35 |
| - public override Action<object, TProperty> CreateFieldSetter<TProperty>(FieldInfo fieldInfo) |
36 |
| - => s_cache.GetOrAdd((nameof(CreateFieldSetter), typeof(TProperty), fieldInfo), static key => s_sourceAccessor.CreateFieldSetter<TProperty>((FieldInfo)key.member!)); |
| 36 | + public override Func<object, TProperty> CreateFieldGetter<TProperty>(FieldInfo fieldInfo) => |
| 37 | + _cache.GetOrAdd( |
| 38 | + key: (nameof(CreateFieldGetter), typeof(TProperty), fieldInfo), |
| 39 | + valueFactory: key => _sourceAccessor.CreateFieldGetter<TProperty>((FieldInfo)key.member!)); |
37 | 40 |
|
38 |
| - [RequiresUnreferencedCode(IEnumerableConverterFactoryHelpers.ImmutableConvertersUnreferencedCodeMessage)] |
39 |
| - public override Func<IEnumerable<KeyValuePair<TKey, TValue>>, TCollection> CreateImmutableDictionaryCreateRangeDelegate<TCollection, TKey, TValue>() |
40 |
| - => s_cache.GetOrAdd((nameof(CreateImmutableDictionaryCreateRangeDelegate), typeof((TCollection, TKey, TValue)), null), |
41 |
| - static (_) => s_sourceAccessor.CreateImmutableDictionaryCreateRangeDelegate<TCollection, TKey, TValue>()); |
| 41 | + public override Action<object, TProperty> CreateFieldSetter<TProperty>(FieldInfo fieldInfo) => |
| 42 | + _cache.GetOrAdd( |
| 43 | + key: (nameof(CreateFieldSetter), typeof(TProperty), fieldInfo), |
| 44 | + valueFactory: key => _sourceAccessor.CreateFieldSetter<TProperty>((FieldInfo)key.member!)); |
42 | 45 |
|
43 |
| - [RequiresUnreferencedCode(IEnumerableConverterFactoryHelpers.ImmutableConvertersUnreferencedCodeMessage)] |
44 |
| - public override Func<IEnumerable<TElement>, TCollection> CreateImmutableEnumerableCreateRangeDelegate<TCollection, TElement>() |
45 |
| - => s_cache.GetOrAdd((nameof(CreateImmutableEnumerableCreateRangeDelegate), typeof((TCollection, TElement)), null), |
46 |
| - static (_) => s_sourceAccessor.CreateImmutableEnumerableCreateRangeDelegate<TCollection, TElement>()); |
| 46 | + public override Func<IEnumerable<KeyValuePair<TKey, TValue>>, TCollection> CreateImmutableDictionaryCreateRangeDelegate<TCollection, TKey, TValue>() => |
| 47 | + _cache.GetOrAdd( |
| 48 | + key: (nameof(CreateImmutableDictionaryCreateRangeDelegate), typeof((TCollection, TKey, TValue)), null), |
| 49 | + valueFactory: _ => _sourceAccessor.CreateImmutableDictionaryCreateRangeDelegate<TCollection, TKey, TValue>()); |
47 | 50 |
|
48 |
| - public override Func<object[], T> CreateParameterizedConstructor<T>(ConstructorInfo constructor) |
49 |
| - => s_cache.GetOrAdd((nameof(CreateParameterizedConstructor), typeof(T), constructor), static key => s_sourceAccessor.CreateParameterizedConstructor<T>((ConstructorInfo)key.member!)); |
| 51 | + public override Func<IEnumerable<TElement>, TCollection> CreateImmutableEnumerableCreateRangeDelegate<TCollection, TElement>() => |
| 52 | + _cache.GetOrAdd( |
| 53 | + key: (nameof(CreateImmutableEnumerableCreateRangeDelegate), typeof((TCollection, TElement)), null), |
| 54 | + valueFactory: _ => _sourceAccessor.CreateImmutableEnumerableCreateRangeDelegate<TCollection, TElement>()); |
50 | 55 |
|
51 |
| - public override JsonTypeInfo.ParameterizedConstructorDelegate<T, TArg0, TArg1, TArg2, TArg3>? CreateParameterizedConstructor<T, TArg0, TArg1, TArg2, TArg3>(ConstructorInfo constructor) |
52 |
| - => s_cache.GetOrAdd((nameof(CreateParameterizedConstructor), typeof(T), constructor), static key => s_sourceAccessor.CreateParameterizedConstructor<T, TArg0, TArg1, TArg2, TArg3>((ConstructorInfo)key.member!)); |
| 56 | + public override Func<object[], T> CreateParameterizedConstructor<T>(ConstructorInfo constructor) => |
| 57 | + _cache.GetOrAdd( |
| 58 | + key: (nameof(CreateParameterizedConstructor), typeof(T), constructor), |
| 59 | + valueFactory: key => _sourceAccessor.CreateParameterizedConstructor<T>((ConstructorInfo)key.member!)); |
53 | 60 |
|
54 |
| - public override Func<object, TProperty> CreatePropertyGetter<TProperty>(PropertyInfo propertyInfo) |
55 |
| - => s_cache.GetOrAdd((nameof(CreatePropertyGetter), typeof(TProperty), propertyInfo), static key => s_sourceAccessor.CreatePropertyGetter<TProperty>((PropertyInfo)key.member!)); |
| 61 | + public override JsonTypeInfo.ParameterizedConstructorDelegate<T, TArg0, TArg1, TArg2, TArg3>? CreateParameterizedConstructor<T, TArg0, TArg1, TArg2, TArg3>(ConstructorInfo constructor) => |
| 62 | + _cache.GetOrAdd( |
| 63 | + key: (nameof(CreateParameterizedConstructor), typeof(T), constructor), |
| 64 | + valueFactory: key => _sourceAccessor.CreateParameterizedConstructor<T, TArg0, TArg1, TArg2, TArg3>((ConstructorInfo)key.member!)); |
56 | 65 |
|
57 |
| - public override Action<object, TProperty> CreatePropertySetter<TProperty>(PropertyInfo propertyInfo) |
58 |
| - => s_cache.GetOrAdd((nameof(CreatePropertySetter), typeof(TProperty), propertyInfo), static key => s_sourceAccessor.CreatePropertySetter<TProperty>((PropertyInfo)key.member!)); |
| 66 | + public override Func<object, TProperty> CreatePropertyGetter<TProperty>(PropertyInfo propertyInfo) => |
| 67 | + _cache.GetOrAdd( |
| 68 | + key: (nameof(CreatePropertyGetter), typeof(TProperty), propertyInfo), |
| 69 | + valueFactory: key => _sourceAccessor.CreatePropertyGetter<TProperty>((PropertyInfo)key.member!)); |
| 70 | + |
| 71 | + public override Action<object, TProperty> CreatePropertySetter<TProperty>(PropertyInfo propertyInfo) => |
| 72 | + _cache.GetOrAdd( |
| 73 | + key: (nameof(CreatePropertySetter), typeof(TProperty), propertyInfo), |
| 74 | + valueFactory: key => _sourceAccessor.CreatePropertySetter<TProperty>((PropertyInfo)key.member!)); |
59 | 75 | }
|
60 | 76 | }
|
61 | 77 | #endif
|
0 commit comments