44 */
55
66using System ;
7+ using System . Collections . Concurrent ;
8+ using System . Reflection ;
79using System . Threading . Tasks ;
10+ using Jose ;
811using Microsoft . Azure . WebJobs ;
912using Microsoft . Azure . WebJobs . Extensions . DurableTask ;
1013using Microsoft . Extensions . Logging ;
14+ using Microsoft . VisualStudio . Services . Common ;
1115using TeamCloud . Model . Commands . Core ;
1216
1317namespace TeamCloud . Orchestrator . Command ;
@@ -20,6 +24,21 @@ public abstract class CommandHandler<TCommand> : CommandHandler, ICommandHandler
2024
2125public abstract class CommandHandler : ICommandHandler
2226{
27+ private static readonly ConcurrentDictionary < Type , ConcurrentDictionary < Type , MethodInfo > > HandleMethodCache = new ConcurrentDictionary < Type , ConcurrentDictionary < Type , MethodInfo > > ( ) ;
28+
29+ private MethodInfo GetHandleMethod ( ICommand command ) => HandleMethodCache
30+ . GetOrAdd ( GetType ( ) , handlerType => new ConcurrentDictionary < Type , MethodInfo > ( ) )
31+ . GetOrAdd ( command . GetType ( ) , commandType =>
32+ {
33+ var handlerInterface = typeof ( ICommandHandler < > )
34+ . MakeGenericType ( commandType ) ;
35+
36+ if ( handlerInterface . IsAssignableFrom ( GetType ( ) ) )
37+ return handlerInterface . GetMethod ( nameof ( HandleAsync ) , new Type [ ] { command . GetType ( ) , typeof ( IAsyncCollector < ICommand > ) , typeof ( IDurableOrchestrationContext ) , typeof ( ILogger ) } ) ;
38+
39+ return null ;
40+ } ) ;
41+
2342 public const string ProcessorQueue = "command-processor" ;
2443 public const string MonitorQueue = "command-monitor" ;
2544
@@ -30,9 +49,7 @@ public virtual bool CanHandle(ICommand command)
3049 if ( command is null )
3150 throw new ArgumentNullException ( nameof ( command ) ) ;
3251
33- return typeof ( ICommandHandler < > )
34- . MakeGenericType ( command . GetType ( ) )
35- . IsAssignableFrom ( GetType ( ) ) ;
52+ return GetHandleMethod ( command ) is not null ;
3653 }
3754
3855 public virtual Task < ICommandResult > HandleAsync ( ICommand command , IAsyncCollector < ICommand > commandQueue , IDurableOrchestrationContext orchestrationContext , ILogger log )
@@ -42,11 +59,7 @@ public virtual Task<ICommandResult> HandleAsync(ICommand command, IAsyncCollecto
4259
4360 if ( CanHandle ( command ) )
4461 {
45- var handleMethod = typeof ( ICommandHandler < > )
46- . MakeGenericType ( command . GetType ( ) )
47- . GetMethod ( nameof ( HandleAsync ) , new Type [ ] { command . GetType ( ) , typeof ( IAsyncCollector < ICommand > ) , typeof ( IDurableOrchestrationContext ) , typeof ( ILogger ) } ) ;
48-
49- return ( Task < ICommandResult > ) handleMethod
62+ return ( Task < ICommandResult > ) GetHandleMethod ( command )
5063 . Invoke ( this , new object [ ] { command , commandQueue , orchestrationContext , log } ) ;
5164 }
5265
0 commit comments