profileShare

rasmusjy / splitapp-backend-microservices

Read-only snapshot

No repository description.

main default branch 501 files Expires Sep 13, 2026, 9:06 AM
MessageDispatcherFactory.cs 1,629 bytes
1 using System.Text.Json;
2 using Microsoft.Extensions.DependencyInjection;
3
4 namespace SplitApp.Shared.Messaging.Internal;
5
6 /// <summary>
7 /// Builds strongly-typed delegate adapters so the consumer loop can dispatch by `Type` lookup
8 /// without per-message reflection. One factory call per registered handler at startup.
9 /// </summary>
10 public static class MessageDispatcherFactory
11 {
12 public static MessageDispatcher CreateEventDispatcher<TEvent, THandler>()
13 where TEvent : IIntegrationEvent
14 where THandler : class, IEventHandler<TEvent>
15 {
16 return async (body, scopedProvider, ct) =>
17 {
18 var evt = JsonSerializer.Deserialize<TEvent>(body.Span)
19 ?? throw new InvalidOperationException($"Failed to deserialize {typeof(TEvent).Name}");
20 var handler = scopedProvider.GetRequiredService<THandler>();
21 await handler.HandleAsync(evt, ct);
22 return null;
23 };
24 }
25
26 public static MessageDispatcher CreateRequestDispatcher<TRequest, TResponse, THandler>()
27 where TRequest : IIntegrationRequest<TResponse>
28 where THandler : class, IRequestHandler<TRequest, TResponse>
29 {
30 return async (body, scopedProvider, ct) =>
31 {
32 var req = JsonSerializer.Deserialize<TRequest>(body.Span)
33 ?? throw new InvalidOperationException($"Failed to deserialize {typeof(TRequest).Name}");
34 var handler = scopedProvider.GetRequiredService<THandler>();
35 var resp = await handler.HandleAsync(req, ct);
36 return JsonSerializer.SerializeToUtf8Bytes(resp);
37 };
38 }
39 }
40