From 6403514bd14cc5c4adf488d005d7e6b9cc4a58a9 Mon Sep 17 00:00:00 2001 From: Benjamin SPETH Date: Mon, 25 Nov 2024 16:36:31 +0100 Subject: [PATCH] Added new generic handler --- .../Configuration/MessageReceptionBuilder.cs | 7 +++++- .../MessageReceptionRegistration.cs | 23 ++++++++++++++++++- .../IMessageReceptionHandler.cs | 18 ++++++++++++++- .../Reception/MessageReceptionHandler.cs | 17 +++++++++++--- .../Reception/ReceptionRegistrationBuilder.cs | 18 +++++++++++++++ 5 files changed, 77 insertions(+), 6 deletions(-) diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/MessageReceptionBuilder.cs b/src/Ev.ServiceBus.Abstractions/Configuration/MessageReceptionBuilder.cs index 2169353..e7db13f 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/MessageReceptionBuilder.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/MessageReceptionBuilder.cs @@ -8,13 +8,18 @@ public class MessageReceptionBuilder public Type HandlerType => _registration.HandlerType; - public Type PayloadType => _registration.PayloadType; + public Type? PayloadType => _registration.PayloadType; public MessageReceptionBuilder(ClientOptions clientOptions, Type payloadType, Type handlerType) { _registration = new MessageReceptionRegistration(clientOptions, payloadType, handlerType); } + public MessageReceptionBuilder(ClientOptions clientOptions, string payloadTypeId, Type handlerType) + { + _registration = new MessageReceptionRegistration(clientOptions, payloadTypeId, handlerType); + } + /// /// Sets the PayloadTypeId (by default it will take the of the payload object) /// diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/MessageReceptionRegistration.cs b/src/Ev.ServiceBus.Abstractions/Configuration/MessageReceptionRegistration.cs index e0c8387..0451e55 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/MessageReceptionRegistration.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/MessageReceptionRegistration.cs @@ -2,6 +2,12 @@ namespace Ev.ServiceBus.Abstractions; +public enum HandlerMode +{ + Typed = 1, + Generic +} + public class MessageReceptionRegistration { public MessageReceptionRegistration(ClientOptions clientOptions, Type payloadType, Type handlerType) @@ -10,6 +16,16 @@ public MessageReceptionRegistration(ClientOptions clientOptions, Type payloadTyp PayloadType = payloadType; HandlerType = handlerType; PayloadTypeId = PayloadType.Name; + HandlerMode = HandlerMode.Typed; + } + + public MessageReceptionRegistration(ClientOptions clientOptions, string payloadTypeId, Type handlerType) + { + Options = clientOptions; + PayloadType = null; + HandlerType = handlerType; + PayloadTypeId = payloadTypeId; + HandlerMode = HandlerMode.Generic; } /// @@ -20,7 +36,7 @@ public MessageReceptionRegistration(ClientOptions clientOptions, Type payloadTyp /// /// The type the receiving message wil be deserialized into. /// - public Type PayloadType { get; } + public Type? PayloadType { get; } /// /// The class that will be resolved to process the incoming message. @@ -31,4 +47,9 @@ public MessageReceptionRegistration(ClientOptions clientOptions, Type payloadTyp /// The unique identifier of this payload's type. /// public string PayloadTypeId { get; internal set; } + + /// + /// The unique identifier of this payload's type. + /// + public HandlerMode HandlerMode { get; internal set; } } \ No newline at end of file diff --git a/src/Ev.ServiceBus.Abstractions/MessageReception/IMessageReceptionHandler.cs b/src/Ev.ServiceBus.Abstractions/MessageReception/IMessageReceptionHandler.cs index d945e7b..a724c87 100644 --- a/src/Ev.ServiceBus.Abstractions/MessageReception/IMessageReceptionHandler.cs +++ b/src/Ev.ServiceBus.Abstractions/MessageReception/IMessageReceptionHandler.cs @@ -1,5 +1,7 @@ -using System.Threading; +using System; +using System.Threading; using System.Threading.Tasks; +using Ev.ServiceBus.Abstractions.MessageReception; namespace Ev.ServiceBus.Reception; @@ -16,4 +18,18 @@ public interface IMessageReceptionHandler /// /// Task Handle(TMessagePayload @event, CancellationToken cancellationToken); +} + +/// +/// Base interface for a message reception handler. +/// +public interface IMessageReceptionHandler +{ + /// + /// Called whenever a message of linked payloadTypeId is received. + /// + /// + /// + /// + Task Handle(BinaryData body, IMessageMetadata messageMetadata, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/src/Ev.ServiceBus/Reception/MessageReceptionHandler.cs b/src/Ev.ServiceBus/Reception/MessageReceptionHandler.cs index a07e05e..34474fd 100644 --- a/src/Ev.ServiceBus/Reception/MessageReceptionHandler.cs +++ b/src/Ev.ServiceBus/Reception/MessageReceptionHandler.cs @@ -62,9 +62,20 @@ public async Task HandleMessageAsync(MessageContext context) if (context.CancellationToken.IsCancellationRequested) return; - var @event = _messagePayloadSerializer.DeSerializeBody(context.Message.Body.ToArray(), context.ReceptionRegistration!.PayloadType); - var methodInfo = _callHandlerInfo.MakeGenericMethod(context.ReceptionRegistration.PayloadType); - await ((Task) methodInfo.Invoke(this, new[] { context.ReceptionRegistration, @event, context.CancellationToken })!); + switch (context.ReceptionRegistration.HandlerMode) + { + case HandlerMode.Typed: + var @event = _messagePayloadSerializer.DeSerializeBody(context.Message.Body.ToArray(), context.ReceptionRegistration!.PayloadType); + var methodInfo = _callHandlerInfo.MakeGenericMethod(context.ReceptionRegistration.PayloadType); + await ((Task) methodInfo.Invoke(this, new[] { context.ReceptionRegistration, @event, context.CancellationToken })!); + break; + case HandlerMode.Generic: + var handler = (IMessageReceptionHandler) _provider.GetRequiredService(context.ReceptionRegistration.HandlerType); + + await handler.Handle(context.Message.Body, _messageMetadataAccessor.Metadata!, context.CancellationToken); + break; + default: throw new ArgumentOutOfRangeException(); + } } catch (Exception ex) { diff --git a/src/Ev.ServiceBus/Reception/ReceptionRegistrationBuilder.cs b/src/Ev.ServiceBus/Reception/ReceptionRegistrationBuilder.cs index 637e0df..84506a5 100644 --- a/src/Ev.ServiceBus/Reception/ReceptionRegistrationBuilder.cs +++ b/src/Ev.ServiceBus/Reception/ReceptionRegistrationBuilder.cs @@ -55,6 +55,24 @@ public MessageReceptionBuilder RegisterReception() return builder; } + /// + /// Registers a generic handler to receive message from a given PayloadTypeId. + /// + /// + /// The handler that will receive the raw data + /// + public MessageReceptionBuilder RegisterReception(string payloadTypeId) + where THandler : class, IMessageReceptionHandler + { + _services.TryAddScoped(); + var builder = new MessageReceptionBuilder(_options, payloadTypeId, typeof(THandler)); + _services.Configure(options => + { + options.RegisterReception(builder); + }); + return builder; + } + /// /// Registers a class as a payload to receive and deserialize through the current resource. ///