Skip to content

Commit d2fc15d

Browse files
committed
Support inherited handler methods
1 parent a46dfed commit d2fc15d

2 files changed

Lines changed: 33 additions & 5 deletions

File tree

src/Foundatio.Mediator/HandlerAnalyzer.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ public static List<HandlerInfo> GetHandlers(GeneratorSyntaxContext context)
8484

8585
bool treatAsHandlerClass = nameMatches || implementsMarker || hasClassHandlerAttribute;
8686

87-
var handlerMethods = classSymbol.GetMembers()
88-
.OfType<IMethodSymbol>()
87+
var handlerMethods = GetMethods(classSymbol)
8988
.Where(m => IsHandlerMethod(m, context.SemanticModel.Compilation, treatAsHandlerClass))
9089
.ToList();
9190

@@ -174,6 +173,32 @@ private static bool IsHandlerMethod(IMethodSymbol method, Compilation compilatio
174173
return true;
175174
}
176175

176+
private static IEnumerable<IMethodSymbol> GetMethods(INamedTypeSymbol targetSymbol, bool includeBaseMethods = true)
177+
{
178+
var methods = new Dictionary<string, IMethodSymbol>();
179+
180+
var currentSymbol = targetSymbol;
181+
182+
while (currentSymbol != null)
183+
{
184+
var methodSymbols = currentSymbol
185+
.GetMembers()
186+
.Where(m => m.Kind == SymbolKind.Method)
187+
.OfType<IMethodSymbol>()
188+
.Where(p => !methods.ContainsKey(p.Name));
189+
190+
foreach (var methodSymbol in methodSymbols)
191+
methods.Add(methodSymbol.Name, methodSymbol);
192+
193+
if (!includeBaseMethods)
194+
break;
195+
196+
currentSymbol = currentSymbol.BaseType;
197+
}
198+
199+
return methods.Values;
200+
}
201+
177202
private static readonly string[] ValidHandlerMethodNames = [
178203
"Handle", "HandleAsync",
179204
"Handles", "HandlesAsync",

tests/Foundatio.Mediator.Tests/OpenGenericHandlerTests.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,18 @@ namespace Foundatio.Mediator.Tests;
55
public record UpdateEntity<T>(T Entity) : ICommand;
66
public record UpdateEntityPair<T1, T2>(T1 First, T2 Second) : ICommand;
77

8-
public class EntityHandler<T>
8+
public class EntityHandlerBase<T>
99
{
10-
public Task HandleAsync(UpdateEntity<T> command, CancellationToken cancellationToken)
10+
public Task HandlesAsync(UpdateEntity<T> command, CancellationToken cancellationToken)
1111
{
12-
// no-op
1312
return Task.CompletedTask;
1413
}
1514
}
1615

16+
public class EntityHandler<T> : EntityHandlerBase<T>
17+
{
18+
}
19+
1720
public class EntityPairHandler<T1, T2>
1821
{
1922
public Task HandleAsync(UpdateEntityPair<T1, T2> command, CancellationToken cancellationToken)

0 commit comments

Comments
 (0)