@@ -18,6 +18,8 @@ public sealed class ReflectionCacheSet
1818
1919 private readonly ConcurrentDictionary < string , IReflectionCache > _caches = new ( ) ;
2020
21+ private readonly List < WeakReference < IReflectionCache > > _externalCaches = new ( ) ;
22+
2123 /// <summary>
2224 /// Initializes a new instance of the <see cref="ReflectionCacheSet"/> class.
2325 /// </summary>
@@ -101,6 +103,26 @@ public TCacheStore GetOrCreateCache<TCacheStore>(string cacheName, Func<string,
101103 }
102104 }
103105
106+ /// <summary>
107+ /// Register an externally-owned <see cref="IReflectionCache"/> so it participates
108+ /// in <see cref="Clear()"/> and <see cref="Clear(ReflectionCacheClearPredicate)"/> calls.
109+ /// The cache is held via a weak reference so it does not prevent garbage collection
110+ /// of the owning object (e.g., a container or registration source).
111+ /// </summary>
112+ /// <param name="cache">The cache to register.</param>
113+ public void RegisterExternalCache ( IReflectionCache cache )
114+ {
115+ if ( cache is null )
116+ {
117+ throw new ArgumentNullException ( nameof ( cache ) ) ;
118+ }
119+
120+ lock ( _externalCaches )
121+ {
122+ _externalCaches . Add ( new WeakReference < IReflectionCache > ( cache ) ) ;
123+ }
124+ }
125+
104126 /// <summary>
105127 /// Clear the internal reflection cache. Only call this method if you are
106128 /// dynamically unloading types from the process; calling this method
@@ -117,6 +139,8 @@ public void Clear()
117139 {
118140 cache . Clear ( ) ;
119141 }
142+
143+ ClearExternalCaches ( static cache => cache . Clear ( ) ) ;
120144 }
121145
122146 /// <summary>
@@ -139,6 +163,8 @@ public void Clear(ReflectionCacheClearPredicate predicate)
139163 {
140164 cache . Clear ( predicate ) ;
141165 }
166+
167+ ClearExternalCaches ( cache => cache . Clear ( predicate ) ) ;
142168 }
143169
144170 /// <summary>
@@ -173,6 +199,25 @@ private static bool TryGetSharedCache([NotNullWhen(true)] out ReflectionCacheSet
173199 return _sharedSet . TryGetTarget ( out sharedCache ) ;
174200 }
175201
202+ private void ClearExternalCaches ( Action < IReflectionCache > clearAction )
203+ {
204+ lock ( _externalCaches )
205+ {
206+ for ( var i = _externalCaches . Count - 1 ; i >= 0 ; i -- )
207+ {
208+ if ( _externalCaches [ i ] . TryGetTarget ( out var cache ) )
209+ {
210+ clearAction ( cache ) ;
211+ }
212+ else
213+ {
214+ // Prune dead references.
215+ _externalCaches . RemoveAt ( i ) ;
216+ }
217+ }
218+ }
219+ }
220+
176221 private IEnumerable < IReflectionCache > GetAllCaches ( )
177222 {
178223 foreach ( var externalItem in _caches )
0 commit comments