Skip to content

Commit d9748c6

Browse files
committed
Add ability to show all registered handlers
1 parent 3c60e1f commit d9748c6

5 files changed

Lines changed: 48 additions & 3 deletions

File tree

samples/ModularMonolithSample/src/Orders.Module/Api/OrdersApi.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ public static void MapOrdersEndpoints(this IEndpointRouteBuilder endpoints)
5858

5959
group.MapPost("/action", async (EntityAction<Order> command, IMediator mediator) =>
6060
{
61+
var foundatioMediator = (Mediator)mediator;
62+
foundatioMediator.ShowRegisteredHandlers();
63+
6164
var result = await mediator.InvokeAsync<Result<Order>>(command);
6265
return result.ToCreatedResult($"/api/orders/{result.Value?.Id}");
6366
})

src/Foundatio.Mediator.Abstractions/HandlerRegistration.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ public class HandlerRegistration
99
/// Creates a new handler registration
1010
/// </summary>
1111
/// <param name="messageTypeName">The fully qualified type name of the message</param>
12+
/// <param name="handlerClassName">The fully qualified type name of the generated handler wrapper class</param>
1213
/// <param name="handleAsync">The delegate to handle the message asynchronously</param>
1314
/// <param name="handle">The delegate to handle the message synchronously (null for async-only handlers)</param>
1415
/// <param name="isAsync">Whether the handler supports async operations</param>
15-
public HandlerRegistration(string messageTypeName, HandleAsyncDelegate handleAsync, HandleDelegate? handle, bool isAsync)
16+
public HandlerRegistration(string messageTypeName, string handlerClassName, HandleAsyncDelegate handleAsync, HandleDelegate? handle, bool isAsync)
1617
{
1718
MessageTypeName = messageTypeName;
19+
HandlerClassName = handlerClassName;
1820
HandleAsync = handleAsync;
1921
Handle = handle;
2022
IsAsync = isAsync;
@@ -25,6 +27,11 @@ public HandlerRegistration(string messageTypeName, HandleAsyncDelegate handleAsy
2527
/// </summary>
2628
public string MessageTypeName { get; }
2729

30+
/// <summary>
31+
/// The fully qualified type name of the generated handler wrapper class
32+
/// </summary>
33+
public string HandlerClassName { get; }
34+
2835
/// <summary>
2936
/// The delegate to handle the message
3037
/// </summary>

src/Foundatio.Mediator.Abstractions/Mediator.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System.Collections.Concurrent;
22
using System.Diagnostics;
3+
using System.Text;
34
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.Extensions.Logging;
46

57
namespace Foundatio.Mediator;
68

@@ -51,6 +53,26 @@ public ValueTask PublishAsync(object message, CancellationToken cancellationToke
5153
return _configuration.NotificationPublisher.PublishAsync(this, handlersList, message, cancellationToken);
5254
}
5355

56+
public void ShowRegisteredHandlers()
57+
{
58+
var logger = _serviceProvider.GetRequiredService<ILogger<Mediator>>();
59+
var registrations = _serviceProvider.GetServices<HandlerRegistration>().ToArray();
60+
if (!registrations.Any())
61+
{
62+
logger.LogInformation("No handlers registered.");
63+
return;
64+
}
65+
66+
var sb = new StringBuilder();
67+
sb.AppendLine("Registered Handlers:");
68+
foreach (var registration in registrations.OrderBy(r => r.MessageTypeName).ThenBy(r => r.HandlerClassName))
69+
{
70+
sb.AppendLine($"- Message: {registration.MessageTypeName}, Handler: {registration.HandlerClassName}, IsAsync: {registration.IsAsync}");
71+
}
72+
73+
logger.LogInformation(sb.ToString());
74+
}
75+
5476
[DebuggerStepThrough]
5577
private InvokeAsyncDelegate GetInvokeAsyncDelegate(Type messageType)
5678
{

src/Foundatio.Mediator.Abstractions/MediatorExtensions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,19 @@ public static IServiceCollection AddMediator(this IServiceCollection services, A
5757
return services.AddMediator(configurationBuilder.Build());
5858
}
5959

60+
/// <summary>
61+
/// Adds a handler registration to the service collection.
62+
/// </summary>
63+
/// <param name="services"></param>
64+
/// <param name="registration"></param>
65+
/// <returns></returns>
66+
public static IServiceCollection AddHandler(this IServiceCollection services, HandlerRegistration registration)
67+
{
68+
services.AddKeyedSingleton<HandlerRegistration>(registration.MessageTypeName);
69+
services.AddSingleton(registration);
70+
return services;
71+
}
72+
6073
private static bool IsAssemblyMarkedWithFoundatioHandlerModule(Assembly assembly)
6174
{
6275
return assembly.GetCustomAttributes(typeof(FoundatioHandlerModuleAttribute), false).Any();

src/Foundatio.Mediator/DIRegistrationGenerator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ public static void Execute(SourceProductionContext context, List<HandlerInfo> ha
5959
}
6060

6161
// Use reflection FullName so nested types resolve with '+' and match runtime Type.FullName keys
62-
source.AppendLine($"services.AddKeyedSingleton<HandlerRegistration>(MessageTypeKey.Get(typeof({handler.MessageType.FullName})),");
63-
source.AppendLine($" new HandlerRegistration(");
62+
source.AppendLine($"services.AddHandler(new HandlerRegistration(");
6463
source.AppendLine($" MessageTypeKey.Get(typeof({handler.MessageType.FullName})),");
64+
source.AppendLine($" \"{handlerClassName}\",");
6565

6666
if (handler.IsAsync)
6767
{

0 commit comments

Comments
 (0)