22// The .NET Foundation licenses this file to you under the MIT license.
33
44using System . Collections . Frozen ;
5+ using System . Diagnostics . CodeAnalysis ;
56using System . Text . Json ;
67using Microsoft . EntityFrameworkCore . ChangeTracking . Internal ;
78using Microsoft . EntityFrameworkCore . Cosmos . ChangeTracking . Internal ;
@@ -36,7 +37,7 @@ public CosmosTypeMappingSource(TypeMappingSourceDependencies dependencies)
3637 { typeof ( TimeOnly ) , CosmosTimeOnlyTypeMapping . Default } ,
3738 { typeof ( TimeSpan ) , CosmosTimeSpanTypeMapping . Default } ,
3839 {
39- typeof ( JObject ) , new CosmosTypeMapping (
40+ typeof ( JObject ) , CreateMapping (
4041 typeof ( JObject ) , jsonValueReaderWriter : dependencies . JsonValueReaderWriterSource . FindReaderWriter ( typeof ( JObject ) ) )
4142 }
4243 } . ToFrozenDictionary ( ) ;
@@ -115,10 +116,10 @@ public CosmosTypeMappingSource(TypeMappingSourceDependencies dependencies)
115116 CoreTypeMapping ? typeMapping = null ;
116117 return ! TryFindJsonCollectionMapping ( elementMappingInfo , memoryType . MakeArrayType ( ) , null , ref typeMapping , out var _ , out var readerWriter )
117118 ? null
118- : new CosmosTypeMapping ( clrType , jsonValueReaderWriter : readerWriter )
119- . WithComposedConverter (
120- ( ValueConverter ) Activator . CreateInstance ( typeof ( ReadOnlyMemoryConverter < > ) . MakeGenericType ( memoryType ) ) ! ,
121- ( ValueComparer ) Activator . CreateInstance ( typeof ( ReadOnlyMemoryComparer < > ) . MakeGenericType ( memoryType ) ) ! ) ;
119+ : CreateMapping ( clrType , jsonValueReaderWriter : readerWriter )
120+ . WithComposedConverter (
121+ ( ValueConverter ) Activator . CreateInstance ( typeof ( ReadOnlyMemoryConverter < > ) . MakeGenericType ( memoryType ) ) ! ,
122+ ( ValueComparer ) Activator . CreateInstance ( typeof ( ReadOnlyMemoryComparer < > ) . MakeGenericType ( memoryType ) ) ! ) ;
122123 }
123124
124125 return clrType . IsNumeric ( )
@@ -129,7 +130,7 @@ public CosmosTypeMappingSource(TypeMappingSourceDependencies dependencies)
129130 || clrType == typeof ( DateTimeOffset )
130131 || clrType == typeof ( TimeSpan )
131132 || clrType == typeof ( string )
132- ? new CosmosTypeMapping (
133+ ? CreateMapping (
133134 clrType , jsonValueReaderWriter : Dependencies . JsonValueReaderWriterSource . FindReaderWriter ( clrType ) )
134135 : null ;
135136 }
@@ -155,7 +156,7 @@ public CosmosTypeMappingSource(TypeMappingSourceDependencies dependencies)
155156 out var collectionReaderWriter )
156157 && elementMapping is not null )
157158 {
158- return new CosmosTypeMapping (
159+ return CreateMapping (
159160 clrType ,
160161 elementComparer ,
161162 elementMapping : elementMapping ,
@@ -234,7 +235,7 @@ public CosmosTypeMappingSource(TypeMappingSourceDependencies dependencies)
234235 }
235236 }
236237
237- return new CosmosTypeMapping (
238+ return CreateMapping (
238239 clrType ,
239240 CreateStringDictionaryComparer ( elementMapping , elementType , clrType ) ,
240241 jsonValueReaderWriter : jsonValueReaderWriter ) ;
@@ -245,14 +246,67 @@ public CosmosTypeMappingSource(TypeMappingSourceDependencies dependencies)
245246 return null ;
246247 }
247248
249+ private static CosmosTypeMapping CreateMapping (
250+ Type clrType ,
251+ ValueComparer ? comparer = null ,
252+ ValueComparer ? keyComparer = null ,
253+ CoreTypeMapping ? elementMapping = null ,
254+ JsonValueReaderWriter ? jsonValueReaderWriter = null )
255+ => clrType switch
256+ {
257+ _ when clrType == typeof ( bool ) => Create < bool > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
258+ _ when clrType == typeof ( byte ) => Create < byte > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
259+ _ when clrType == typeof ( sbyte ) => Create < sbyte > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
260+ _ when clrType == typeof ( char ) => Create < char > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
261+ _ when clrType == typeof ( short ) => Create < short > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
262+ _ when clrType == typeof ( ushort ) => Create < ushort > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
263+ _ when clrType == typeof ( int ) => Create < int > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
264+ _ when clrType == typeof ( uint ) => Create < uint > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
265+ _ when clrType == typeof ( long ) => Create < long > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
266+ _ when clrType == typeof ( ulong ) => Create < ulong > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
267+ _ when clrType == typeof ( float ) => Create < float > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
268+ _ when clrType == typeof ( double ) => Create < double > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
269+ _ when clrType == typeof ( decimal ) => Create < decimal > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
270+ _ when clrType == typeof ( string ) => Create < string > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
271+ _ when clrType == typeof ( Guid ) => Create < Guid > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
272+ _ when clrType == typeof ( DateTime ) => Create < DateTime > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
273+ _ when clrType == typeof ( DateTimeOffset ) => Create < DateTimeOffset > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
274+ _ when clrType == typeof ( DateOnly ) => Create < DateOnly > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ,
275+ _ => CreateMappingWithReflection ( clrType , comparer , keyComparer , elementMapping , jsonValueReaderWriter )
276+ } ;
277+
278+ private static CosmosTypeMapping Create <
279+ [ DynamicallyAccessedMembers ( DynamicallyAccessedMemberTypes . PublicMethods | DynamicallyAccessedMemberTypes . PublicProperties ) ] T > (
280+ ValueComparer ? comparer ,
281+ ValueComparer ? keyComparer ,
282+ CoreTypeMapping ? elementMapping ,
283+ JsonValueReaderWriter ? jsonValueReaderWriter )
284+ => comparer is null && keyComparer is null && elementMapping is null && jsonValueReaderWriter is null
285+ ? CosmosTypeMapping < T > . Default
286+ : new CosmosTypeMapping < T > ( comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ;
287+
288+ [ UnconditionalSuppressMessage (
289+ "AOT" , "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling." ,
290+ Justification = "The type mapping source is not used at runtime by NativeAOT applications, which use a compiled model instead." ) ]
291+ private static CosmosTypeMapping CreateMappingWithReflection (
292+ Type clrType ,
293+ ValueComparer ? comparer ,
294+ ValueComparer ? keyComparer ,
295+ CoreTypeMapping ? elementMapping ,
296+ JsonValueReaderWriter ? jsonValueReaderWriter )
297+ {
298+ var genericType = typeof ( CosmosTypeMapping < > ) . MakeGenericType ( clrType ) ;
299+ return comparer is null && keyComparer is null && elementMapping is null && jsonValueReaderWriter is null
300+ ? ( CosmosTypeMapping ) genericType . GetAnyProperty ( nameof ( CosmosTypeMapping < object > . Default ) ) ! . GetValue ( null ) !
301+ : ( CosmosTypeMapping ) Activator . CreateInstance ( genericType , comparer , keyComparer , elementMapping , jsonValueReaderWriter ) ! ;
302+ }
303+
248304 private static ValueComparer CreateStringDictionaryComparer (
249305 CoreTypeMapping elementMapping ,
250306 Type elementType ,
251307 Type dictType ,
252308 bool readOnly = false )
253309 {
254- var unwrappedType = elementType . UnwrapNullableType ( ) ;
255-
256310 return ( ValueComparer ) Activator . CreateInstance (
257311 typeof ( StringDictionaryComparer < , > ) . MakeGenericType ( dictType , elementType ) ,
258312#pragma warning disable EF1001 // Internal EF Core API usage.
0 commit comments