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 | |