From fce393e02c48a82b0c8d032bd4219824e04e0c70 Mon Sep 17 00:00:00 2001 From: sabihoshi Date: Wed, 20 Jul 2022 12:46:47 +0800 Subject: [PATCH] feat: Add Priority in HuTaoMediator --- .../Core/Listeners/CommandHandlingService.cs | 1 + .../Core/Listeners/HuTaoMediator.cs | 34 +++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/HuTao.Services/Core/Listeners/CommandHandlingService.cs b/HuTao.Services/Core/Listeners/CommandHandlingService.cs index b41a333..3598910 100644 --- a/HuTao.Services/Core/Listeners/CommandHandlingService.cs +++ b/HuTao.Services/Core/Listeners/CommandHandlingService.cs @@ -48,6 +48,7 @@ public CommandHandlingService( _services = services; } + [Priority(0)] public async Task Handle(MessageReceivedNotification notification, CancellationToken cancellationToken) { var rawMessage = notification.Message; diff --git a/HuTao.Services/Core/Listeners/HuTaoMediator.cs b/HuTao.Services/Core/Listeners/HuTaoMediator.cs index d36fd73..ac55628 100644 --- a/HuTao.Services/Core/Listeners/HuTaoMediator.cs +++ b/HuTao.Services/Core/Listeners/HuTaoMediator.cs @@ -1,7 +1,10 @@ using System; using System.Collections.Generic; +using System.Linq; +using System.Reflection; using System.Threading; using System.Threading.Tasks; +using Discord.Commands; using MediatR; using Serilog; @@ -19,11 +22,13 @@ protected override Task PublishCore( { _ = Task.Run(async () => { - foreach (var handler in handlers) + var priorities = handlers.Select(h => (Handler: h, GetOrderAttribute(h)?.Priority)); + var ordered = priorities.OrderBy(h => !h.Priority.HasValue).ThenBy(h => h.Priority); + foreach (var handler in ordered) { try { - await handler(notification, cancellationToken); + await handler.Handler(notification, cancellationToken); } catch (Exception ex) when (ex is not (OutOfMemoryException or StackOverflowException)) { @@ -42,4 +47,29 @@ protected override Task PublishCore( return Task.CompletedTask; } + + private static PriorityAttribute? GetOrderAttribute(Func x) + { + var handlerFieldInfo = x.Target?.GetType().GetField("x"); + if (handlerFieldInfo is not { FieldType.IsGenericType: true, FieldType.GenericTypeArguments.Length: 1 }) + return null; + + var type = handlerFieldInfo.GetValue(x.Target)?.GetType(); + var methods = type?.GetMethods(BindingFlags.Instance | BindingFlags.Public); + var method = methods?.FirstOrDefault(m => + { + if (m is not { Name: "Handle" } || m.ReturnType != typeof(Task)) return false; + + var parameters = m.GetParameters(); + if (parameters.Length != 2) return false; + + var first = parameters[0]; + var second = parameters[1]; + + return first.ParameterType == handlerFieldInfo.FieldType.GenericTypeArguments[0] + && second.ParameterType == typeof(CancellationToken); + }); + + return method?.GetCustomAttribute(); + } } \ No newline at end of file