44 */
55
66using System ;
7+ using System . Collections . Concurrent ;
8+ using System . Reflection ;
79using System . Threading . Tasks ;
810using TeamCloud . Model . Data . Core ;
911
1012namespace TeamCloud . Data ;
1113
1214public abstract class DocumentSubscription : IDocumentSubscription
1315{
16+ private static readonly ConcurrentDictionary < Type , ConcurrentDictionary < Type , MethodInfo > > HandleMethodCache = new ConcurrentDictionary < Type , ConcurrentDictionary < Type , MethodInfo > > ( ) ;
17+
18+ private MethodInfo GetHandleMethod ( IContainerDocument containerDocument ) => HandleMethodCache
19+ . GetOrAdd ( GetType ( ) , _ => new ConcurrentDictionary < Type , MethodInfo > ( ) )
20+ . GetOrAdd ( containerDocument . GetType ( ) , containerDocumentType =>
21+ {
22+ var subscriberInterface = typeof ( IDocumentSubscription < > )
23+ . MakeGenericType ( containerDocument . GetType ( ) ) ;
24+
25+ if ( subscriberInterface . IsAssignableFrom ( GetType ( ) ) )
26+ return subscriberInterface . GetMethod ( nameof ( HandleAsync ) , new Type [ ] { containerDocument . GetType ( ) , typeof ( DocumentSubscriptionEvent ) } ) ;
27+
28+ return null ;
29+ } ) ;
30+
1431 public virtual bool CanHandle ( IContainerDocument containerDocument )
1532 {
1633 if ( containerDocument is null )
1734 throw new ArgumentNullException ( nameof ( containerDocument ) ) ;
1835
19- return typeof ( IDocumentSubscription < > ) . MakeGenericType ( containerDocument . GetType ( ) ) . IsAssignableFrom ( GetType ( ) ) ;
36+ return GetHandleMethod ( containerDocument ) is not null ;
2037 }
2138
2239 public virtual Task HandleAsync ( IContainerDocument containerDocument , DocumentSubscriptionEvent subscriptionEvent )
@@ -25,12 +42,7 @@ public virtual Task HandleAsync(IContainerDocument containerDocument, DocumentSu
2542 throw new ArgumentNullException ( nameof ( containerDocument ) ) ;
2643
2744 if ( CanHandle ( containerDocument ) )
28- {
29- return ( Task ) typeof ( IDocumentExpander < > )
30- . MakeGenericType ( containerDocument . GetType ( ) )
31- . GetMethod ( nameof ( HandleAsync ) , new Type [ ] { containerDocument . GetType ( ) , typeof ( DocumentSubscriptionEvent ) } )
32- . Invoke ( this , new object [ ] { containerDocument , subscriptionEvent } ) ;
33- }
45+ return ( Task ) GetHandleMethod ( containerDocument ) . Invoke ( this , new object [ ] { containerDocument , subscriptionEvent } ) ;
3446
3547 throw new NotImplementedException ( $ "Missing document subscription implementation IDocumentSubscription<{ containerDocument . GetType ( ) . Name } > at { GetType ( ) } ") ;
3648 }
0 commit comments