Skip to content

Commit 0bf357e

Browse files
optimized reflection caching
1 parent 9f80483 commit 0bf357e

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

src/TeamCloud.Data/IDocumentSubscription.cs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,36 @@
44
*/
55

66
using System;
7+
using System.Collections.Concurrent;
8+
using System.Reflection;
79
using System.Threading.Tasks;
810
using TeamCloud.Model.Data.Core;
911

1012
namespace TeamCloud.Data;
1113

1214
public 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
}

src/TeamCloud.Orchestrator/Command/CommandHandler.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public abstract class CommandHandler : ICommandHandler
2727
private static readonly ConcurrentDictionary<Type, ConcurrentDictionary<Type, MethodInfo>> HandleMethodCache = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, MethodInfo>>();
2828

2929
private MethodInfo GetHandleMethod(ICommand command) => HandleMethodCache
30-
.GetOrAdd(GetType(), handlerType => new ConcurrentDictionary<Type, MethodInfo>())
30+
.GetOrAdd(GetType(), _ => new ConcurrentDictionary<Type, MethodInfo>())
3131
.GetOrAdd(command.GetType(), commandType =>
3232
{
3333
var handlerInterface = typeof(ICommandHandler<>)
@@ -58,10 +58,7 @@ public virtual Task<ICommandResult> HandleAsync(ICommand command, IAsyncCollecto
5858
throw new ArgumentNullException(nameof(command));
5959

6060
if (CanHandle(command))
61-
{
62-
return (Task<ICommandResult>)GetHandleMethod(command)
63-
.Invoke(this, new object[] { command, commandQueue, orchestrationContext, log });
64-
}
61+
return (Task<ICommandResult>)GetHandleMethod(command).Invoke(this, new object[] { command, commandQueue, orchestrationContext, log });
6562

6663
throw new NotImplementedException($"Missing orchestrator command handler implementation ICommandHandler<{command.GetTypeName(prettyPrint: true)}> at {GetType()}");
6764
}

0 commit comments

Comments
 (0)