@@ -48,17 +48,31 @@ internal IEnumerable<PgTypeInfoResolverFactory> GetPluginResolverFactories()
4848
4949 internal void AddGlobalTypeMappingResolvers ( PgTypeInfoResolverFactory [ ] factories , Func < PgTypeInfoResolverChainBuilder > ? builderFactory = null , bool overwrite = false )
5050 {
51- // Good enough logic to prevent SlimBuilder overriding the normal Builder.
52- if ( overwrite || factories . Length > _typeMappingResolvers . Length )
51+ _lock . EnterWriteLock ( ) ;
52+ try
5353 {
54- _builderFactory = builderFactory ;
55- _typeMappingResolvers = factories ;
56- ResetTypeMappingCache ( ) ;
54+ // Prevent SlimBuilder from overriding the normal Builder.
55+ if ( overwrite || factories . Length > _typeMappingResolvers . Length )
56+ {
57+ _builderFactory = builderFactory ;
58+ _typeMappingResolvers = factories ;
59+ ResetTypeMappingCache ( ) ;
60+ }
61+ }
62+ finally
63+ {
64+ _lock . ExitWriteLock ( ) ;
5765 }
5866 }
5967
60- void ResetTypeMappingCache ( ) => _typeMappingOptions = null ;
68+ void ResetTypeMappingCache ( )
69+ {
70+ Interlocked . Increment ( ref _typeMappingVersion ) ;
71+ _typeMappingOptions = null ;
72+ }
6173
74+ int _typeMappingVersion ;
75+ int _typeMappingCachedVersion = - 1 ;
6276 PgSerializerOptions ? _typeMappingOptions ;
6377 Func < PgTypeInfoResolverChainBuilder > ? _builderFactory ;
6478 JsonSerializerOptions ? _jsonSerializerOptions ;
@@ -67,19 +81,25 @@ PgSerializerOptions TypeMappingOptions
6781 {
6882 get
6983 {
70- if ( _typeMappingOptions is not null )
71- return _typeMappingOptions ;
84+ var version = Volatile . Read ( ref _typeMappingVersion ) ;
85+ if ( _typeMappingOptions is { } options && _typeMappingCachedVersion == version )
86+ return options ;
7287
73- _lock . EnterReadLock ( ) ;
88+ _lock . EnterWriteLock ( ) ;
7489 try
7590 {
91+ version = _typeMappingVersion ;
92+ if ( _typeMappingOptions is not null && _typeMappingCachedVersion == version )
93+ return _typeMappingOptions ;
94+
7695 var builder = _builderFactory ? . Invoke ( ) ?? new ( ) ;
7796 builder . AppendResolverFactory ( _userTypeMapper ) ;
7897 foreach ( var factory in _pluginResolverFactories )
7998 builder . AppendResolverFactory ( factory ) ;
8099 foreach ( var factory in _typeMappingResolvers )
81100 builder . AppendResolverFactory ( factory ) ;
82101 var chain = builder . Build ( ) ;
102+ _typeMappingCachedVersion = version ;
83103 return _typeMappingOptions = new ( PostgresMinimalDatabaseInfo . DefaultTypeCatalog , chain )
84104 {
85105 // This means we don't ever have a missing oid for a datatypename as our canonical format is datatypenames.
@@ -90,7 +110,7 @@ PgSerializerOptions TypeMappingOptions
90110 }
91111 finally
92112 {
93- _lock . ExitReadLock ( ) ;
113+ _lock . ExitWriteLock ( ) ;
94114 }
95115 }
96116 }
0 commit comments