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..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 @@ -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; @@ -138,14 +139,19 @@ public class LocalEventBus : EventBusBase, ILocalEventBus, ISingletonDependency protected override IEnumerable GetHandlerFactories(Type eventType) { - var handlerFactoryList = new List(); - + var handlerFactoryList = 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) + { + handlerFactoryList.Add(new Tuple( + factory, + handlerFactory.Key, + ReflectionHelper.GetAttributesOfMemberOrDeclaringType(factory.GetHandler().EventHandler.GetType()).FirstOrDefault()?.Order ?? 0)); + } } - 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) 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; + } + } + +}