From 0cb497371c2a5123285425b5709ce51eef2ef48c Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 11 May 2023 22:09:52 +0800 Subject: [PATCH 1/2] Add `LocalEventHandlerOrderAttribute`. Resolve #16361 --- .../Local/LocalEventHandlerOrderAttribute.cs | 17 ++++++ .../Volo/Abp/EventBus/Local/LocalEventBus.cs | 15 ++++- .../Abp/EventBus/Local/EventBus_Order_Test.cs | 56 +++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Local/LocalEventHandlerOrderAttribute.cs create mode 100644 framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_Order_Test.cs diff --git a/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Local/LocalEventHandlerOrderAttribute.cs b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Local/LocalEventHandlerOrderAttribute.cs new file mode 100644 index 0000000000..7900885e3e --- /dev/null +++ b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Local/LocalEventHandlerOrderAttribute.cs @@ -0,0 +1,17 @@ +using System; + +namespace Volo.Abp.EventBus.Local; + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] +public class LocalEventHandlerOrderAttribute : Attribute +{ + /// + /// Handlers execute in ascending numeric value of the Order property. + /// + public int Order { get; set; } + + public LocalEventHandlerOrderAttribute(int order) + { + Order = order; + } +} diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs index 9570bf80e1..e1edf3b12f 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; using Volo.Abp.MultiTenancy; +using Volo.Abp.Reflection; using Volo.Abp.Threading; using Volo.Abp.Uow; @@ -140,9 +141,21 @@ public class LocalEventBus : EventBusBase, ILocalEventBus, ISingletonDependency { var handlerFactoryList = new List(); + var handlerWithTypes = new List>(); foreach (var handlerFactory in HandlerFactories.Where(hf => ShouldTriggerEventForHandler(eventType, hf.Key))) { - handlerFactoryList.Add(new EventTypeWithEventHandlerFactories(handlerFactory.Key, handlerFactory.Value)); + foreach (var factory in handlerFactory.Value) + { + handlerWithTypes.Add(new Tuple( + factory, + handlerFactory.Key, + ReflectionHelper.GetAttributesOfMemberOrDeclaringType(factory.GetHandler().EventHandler.GetType()).FirstOrDefault()?.Order ?? 0)); + } + } + + foreach (var handlerWithType in handlerWithTypes.OrderBy(x => x.Item3)) + { + handlerFactoryList.Add(new EventTypeWithEventHandlerFactories(handlerWithType.Item2, new List{ handlerWithType.Item1 })); } return handlerFactoryList.ToArray(); diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_Order_Test.cs b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_Order_Test.cs new file mode 100644 index 0000000000..3bf8c3a7b6 --- /dev/null +++ b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_Order_Test.cs @@ -0,0 +1,56 @@ +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Entities.Events; +using Xunit; + +namespace Volo.Abp.EventBus.Local; + +public class EventBus_Order_Test : EventBusTestBase +{ + public static string HandlerExecuteOrder { get; set; } + + [Fact] + public async Task Handler_Should_Execute_By_Order() + { + HandlerExecuteOrder = ""; + await LocalEventBus.PublishAsync(new MyOrderEventHandlerEventData()); + HandlerExecuteOrder.ShouldBe("321"); + } + + public class MyOrderEventHandlerEventData + { + + } + + public class MyOrderEventHandler : ILocalEventHandler, ITransientDependency + { + public Task HandleEventAsync(MyOrderEventHandlerEventData eventData) + { + HandlerExecuteOrder += "1"; + return Task.CompletedTask; + } + } + + [LocalEventHandlerOrder(-2)] + public class MyOrderEventHandler2 : ILocalEventHandler, ITransientDependency + { + public Task HandleEventAsync(MyOrderEventHandlerEventData eventData) + { + HandlerExecuteOrder += "2"; + return Task.CompletedTask; + } + } + + [LocalEventHandlerOrder(-3)] + public class MyOrderEventHandler3 : ILocalEventHandler, ITransientDependency + { + public Task HandleEventAsync(MyOrderEventHandlerEventData eventData) + { + HandlerExecuteOrder += "3"; + return Task.CompletedTask; + } + } + +} From 8e7f9aa836685768b68accf41571d3e1267c4076 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 12 May 2023 08:34:36 +0800 Subject: [PATCH 2/2] Update LocalEventBus.cs --- .../Volo/Abp/EventBus/Local/LocalEventBus.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs index e1edf3b12f..d73b2f8de9 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs @@ -139,26 +139,19 @@ public class LocalEventBus : EventBusBase, ILocalEventBus, ISingletonDependency protected override IEnumerable GetHandlerFactories(Type eventType) { - var handlerFactoryList = new List(); - - var handlerWithTypes = new List>(); + var handlerFactoryList = new List>(); foreach (var handlerFactory in HandlerFactories.Where(hf => ShouldTriggerEventForHandler(eventType, hf.Key))) { foreach (var factory in handlerFactory.Value) { - handlerWithTypes.Add(new Tuple( + handlerFactoryList.Add(new Tuple( factory, handlerFactory.Key, ReflectionHelper.GetAttributesOfMemberOrDeclaringType(factory.GetHandler().EventHandler.GetType()).FirstOrDefault()?.Order ?? 0)); } } - foreach (var handlerWithType in handlerWithTypes.OrderBy(x => x.Item3)) - { - handlerFactoryList.Add(new EventTypeWithEventHandlerFactories(handlerWithType.Item2, new List{ handlerWithType.Item1 })); - } - - return handlerFactoryList.ToArray(); + return handlerFactoryList.OrderBy(x => x.Item3).Select(x => new EventTypeWithEventHandlerFactories(x.Item2, new List {x.Item1})).ToArray(); } private List GetOrCreateHandlerFactories(Type eventType)