From e82a172598c362c29a386cf5c0c774b94e8b3b7c Mon Sep 17 00:00:00 2001 From: tk Date: Fri, 3 Jan 2025 17:26:23 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E2=9A=A1=20=E4=BA=8B=E4=BB=B6=E6=80=BB?= =?UTF-8?q?=E7=BA=BF=E7=B2=BE=E7=AE=80=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/GlobalUsings.cs | 2 +- .../Dto/Sys/Cache/CacheStatisticsRsp.cs | 5 --- .../Dto/Sys/Cache/GetEntryRsp.cs | 5 --- .../NetAdmin.Domain/Dto/Sys/Menu/MetaInfo.cs | 5 --- .../NetAdmin.Domain/Events/EventData.cs | 21 +++++++++++ .../Events/IEventSourceGeneric.cs | 12 ------- .../Events/SeedDataInsertedEvent.cs | 33 ++--------------- .../Events/SqlCommandAfterEvent.cs | 3 +- .../Events/SqlCommandBeforeEvent.cs | 9 ++--- .../NetAdmin.Domain/Events/SqlCommandEvent.cs | 27 +++----------- .../Events/SyncStructureAfterEvent.cs | 5 +-- .../Events/SyncStructureBeforeEvent.cs | 6 ++-- .../Events/Sys/RequestLogEvent.cs | 33 ++--------------- .../Events/Sys/UserCreatedEvent.cs | 33 ++--------------- .../Events/Sys/UserUpdatedEvent.cs | 33 ++--------------- .../Events/Sys/VerifyCodeCreatedEvent.cs | 33 ++--------------- .../NetAdmin.Domain/NetAdmin.Domain.csproj | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 6 +++- .../NetAdmin.Host/Subscribers/SqlProfiler.cs | 35 ++++++++----------- .../EventBus/DefaultEventPublisher.cs | 34 ++++++++++++++++++ .../EventBus/EventSubscribeAttribute.cs | 7 ++++ .../EventBus/IEventData.cs | 17 +++++++++ .../EventBus/IEventPublisher.cs | 12 +++++++ .../EventBus/IEventSubscriber.cs | 6 ++++ .../NetAdmin.Infrastructure.csproj | 2 +- .../Services/Sys/CaptchaService.cs | 5 --- .../Subscribers/ApiSynchronizer.cs | 4 +-- .../Subscribers/CacheCleaner.cs | 18 +++------- .../Subscribers/EmailCodeSender.cs | 10 +++--- .../Subscribers/OperationLogger.cs | 24 ++++++------- .../Subscribers/SmsCodeSender.cs | 10 +++--- 31 files changed, 170 insertions(+), 287 deletions(-) create mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Events/EventData.cs delete mode 100644 src/backend/NetAdmin/NetAdmin.Domain/Events/IEventSourceGeneric.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/DefaultEventPublisher.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/EventSubscribeAttribute.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventData.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventPublisher.cs create mode 100644 src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventSubscriber.cs diff --git a/src/backend/GlobalUsings.cs b/src/backend/GlobalUsings.cs index f89552ee..b850fec9 100644 --- a/src/backend/GlobalUsings.cs +++ b/src/backend/GlobalUsings.cs @@ -32,7 +32,6 @@ global using Gurion.DataEncryption; global using Gurion.DataValidation; global using Gurion.DependencyInjection; global using Gurion.DynamicApiController; -global using Gurion.EventBus; global using Gurion.SpecificationDocument; global using Gurion.UnifyResult; global using Mapster; @@ -58,6 +57,7 @@ global using NetAdmin.Infrastructure.Configuration.Options.SubNodes.Redis; global using NetAdmin.Infrastructure.Configuration.Options.SubNodes.Upload; global using NetAdmin.Infrastructure.Constant; global using NetAdmin.Infrastructure.Enums; +global using NetAdmin.Infrastructure.EventBus; global using NetAdmin.Infrastructure.Exceptions; global using NetAdmin.Infrastructure.Extensions; global using NetAdmin.Infrastructure.Languages; diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Cache/CacheStatisticsRsp.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Cache/CacheStatisticsRsp.cs index f7b0eb37..565a317a 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Cache/CacheStatisticsRsp.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Cache/CacheStatisticsRsp.cs @@ -15,11 +15,6 @@ public sealed record CacheStatisticsRsp : DataAbstraction , new("redis_version:(.+)", RegexOptions.Compiled) // ]; - /// - /// Initializes a new instance of the class. - /// - public CacheStatisticsRsp() { } - /// /// Initializes a new instance of the class. /// diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Cache/GetEntryRsp.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Cache/GetEntryRsp.cs index 08de42d9..2ea8e4b7 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Cache/GetEntryRsp.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Cache/GetEntryRsp.cs @@ -7,11 +7,6 @@ namespace NetAdmin.Domain.Dto.Sys.Cache; /// public sealed record GetEntryRsp : DataAbstraction { - /// - /// Initializes a new instance of the class. - /// - public GetEntryRsp() { } - /// /// 缓存值 /// diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Menu/MetaInfo.cs b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Menu/MetaInfo.cs index 62407cbb..b5e3c28c 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Menu/MetaInfo.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Dto/Sys/Menu/MetaInfo.cs @@ -7,11 +7,6 @@ namespace NetAdmin.Domain.Dto.Sys.Menu; /// public sealed record MetaInfo : DataAbstraction { - /// - /// Initializes a new instance of the class. - /// - public MetaInfo() { } - /// /// Initializes a new instance of the class. /// diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/EventData.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/EventData.cs new file mode 100644 index 00000000..287264f3 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Domain/Events/EventData.cs @@ -0,0 +1,21 @@ +namespace NetAdmin.Domain.Events; + +/// +/// 事件数据 +/// +public abstract record EventData : DataAbstraction, IEventData +{ + /// + /// Initializes a new instance of the class. + /// + protected EventData(T payLoad) + { + PayLoad = payLoad; + } + + /// + public DateTime CreatedTime { get; init; } = DateTime.Now; + + /// + public T PayLoad { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/IEventSourceGeneric.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/IEventSourceGeneric.cs deleted file mode 100644 index b784b80b..00000000 --- a/src/backend/NetAdmin/NetAdmin.Domain/Events/IEventSourceGeneric.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace NetAdmin.Domain.Events; - -/// -/// 泛型事件源接口 -/// -public interface IEventSourceGeneric : IEventSource -{ - /// - /// 事件承载(携带)数据 - /// - T Data { get; } -} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/SeedDataInsertedEvent.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/SeedDataInsertedEvent.cs index 50abdc2b..9f31034f 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Events/SeedDataInsertedEvent.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Events/SeedDataInsertedEvent.cs @@ -3,36 +3,9 @@ namespace NetAdmin.Domain.Events; /// /// 种子数据插入完毕事件 /// -public sealed record SeedDataInsertedEvent : DataAbstraction, IEventSource +public sealed record SeedDataInsertedEvent : EventData { - /// - /// Initializes a new instance of the class. - /// - public SeedDataInsertedEvent(int insertedCount, bool isConsumeOnce = false) - { - IsConsumeOnce = isConsumeOnce; - InsertedCount = insertedCount; - CreatedTime = DateTime.Now; - EventId = nameof(SeedDataInsertedEvent); - } - /// - public DateTime CreatedTime { get; } - - /// - public string EventId { get; } - - /// - public bool IsConsumeOnce { get; } - - /// - public CancellationToken CancellationToken { get; init; } - - /// - /// 插入数量 - /// - public int InsertedCount { get; set; } - - /// - public object Payload { get; init; } + public SeedDataInsertedEvent(int payLoad) // + : base(payLoad) { } } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandAfterEvent.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandAfterEvent.cs index a320670f..2a765708 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandAfterEvent.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandAfterEvent.cs @@ -12,7 +12,6 @@ public sealed record SqlCommandAfterEvent : SqlCommandBeforeEvent : base(e) { ElapsedMilliseconds = (long)((double)e.ElapsedTicks / Stopwatch.Frequency * 1_000); - EventId = nameof(SqlCommandAfterEvent); } /// @@ -24,6 +23,6 @@ public sealed record SqlCommandAfterEvent : SqlCommandBeforeEvent /// public override string ToString() { - return string.Format(CultureInfo.InvariantCulture, "SQL-{0}: {2} ms {1}", Id, Sql, ElapsedMilliseconds); + return string.Format(CultureInfo.InvariantCulture, "SQL-{0}: {2} ms {1}", Id, PayLoad, ElapsedMilliseconds); } } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandBeforeEvent.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandBeforeEvent.cs index 5a96632a..b7aa988f 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandBeforeEvent.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandBeforeEvent.cs @@ -8,13 +8,8 @@ public record SqlCommandBeforeEvent : SqlCommandEvent /// /// Initializes a new instance of the class. /// - public SqlCommandBeforeEvent(CommandBeforeEventArgs e) - { - Identifier = e.Identifier; - Sql = e.Command.ParameterFormat().RemoveWrapped(); - EventId = nameof(SqlCommandBeforeEvent); - CreatedTime = DateTime.Now; - } + public SqlCommandBeforeEvent(CommandBeforeEventArgs e) // + : base(e.Command.ParameterFormat().RemoveWrapped(), e.Identifier) { } /// public override string ToString() diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandEvent.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandEvent.cs index 8d2c6e73..9d5034cc 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandEvent.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Events/SqlCommandEvent.cs @@ -3,31 +3,17 @@ namespace NetAdmin.Domain.Events; /// /// Sql命令事件 /// -public abstract record SqlCommandEvent : DataAbstraction, IEventSource +public abstract record SqlCommandEvent : EventData { /// /// Initializes a new instance of the class. /// - protected SqlCommandEvent(bool isConsumeOnce = false) + protected SqlCommandEvent(string payLoad, Guid identifier) // + : base(payLoad) { - IsConsumeOnce = isConsumeOnce; + Identifier = identifier; } - /// - public bool IsConsumeOnce { get; } - - /// - public CancellationToken CancellationToken { get; init; } - - /// - public DateTime CreatedTime { get; protected init; } - - /// - public string EventId { get; protected init; } - - /// - public object Payload { get; init; } - /// /// 标识符缩写 /// @@ -37,9 +23,4 @@ public abstract record SqlCommandEvent : DataAbstraction, IEventSource /// 标识符,可将 CommandBefore 与 CommandAfter 进行匹配 /// protected Guid Identifier { get; init; } - - /// - /// 关联的Sql语句 - /// - protected string Sql { get; init; } } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/SyncStructureAfterEvent.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/SyncStructureAfterEvent.cs index 2bdee6ac..a64bc6b0 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Events/SyncStructureAfterEvent.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Events/SyncStructureAfterEvent.cs @@ -9,10 +9,7 @@ public sealed record SyncStructureAfterEvent : SyncStructureBeforeEvent /// Initializes a new instance of the class. /// public SyncStructureAfterEvent(SyncStructureBeforeEventArgs e) // - : base(e) - { - EventId = nameof(SyncStructureAfterEvent); - } + : base(e) { } /// public override string ToString() diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/SyncStructureBeforeEvent.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/SyncStructureBeforeEvent.cs index a1327036..e3dccb47 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Events/SyncStructureBeforeEvent.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Events/SyncStructureBeforeEvent.cs @@ -8,11 +8,9 @@ public record SyncStructureBeforeEvent : SqlCommandEvent /// /// Initializes a new instance of the class. /// - public SyncStructureBeforeEvent(SyncStructureBeforeEventArgs e) + public SyncStructureBeforeEvent(SyncStructureBeforeEventArgs e) // + : base(null, e.Identifier) { - Identifier = e.Identifier; - EventId = nameof(SyncStructureBeforeEvent); - CreatedTime = DateTime.Now; EntityTypes = e.EntityTypes; } diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/RequestLogEvent.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/RequestLogEvent.cs index 37dff4bf..16a5cb5d 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/RequestLogEvent.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/RequestLogEvent.cs @@ -5,36 +5,9 @@ namespace NetAdmin.Domain.Events.Sys; /// /// 请求日志事件 /// -public sealed record RequestLogEvent : DataAbstraction, IEventSourceGeneric +public sealed record RequestLogEvent : EventData { - /// - /// Initializes a new instance of the class. - /// - public RequestLogEvent(CreateRequestLogReq data, bool isConsumeOnce = false, object payload = null, DateTime createdTime = default - , CancellationToken cancellationToken = default) - { - Data = data; - IsConsumeOnce = isConsumeOnce; - Payload = payload; - CreatedTime = createdTime; - CancellationToken = cancellationToken; - } - /// - public CancellationToken CancellationToken { get; } - - /// - public DateTime CreatedTime { get; } - - /// - public CreateRequestLogReq Data { get; } - - /// - public string EventId => nameof(RequestLogEvent); - - /// - public bool IsConsumeOnce { get; } - - /// - public object Payload { get; } + public RequestLogEvent(CreateRequestLogReq payLoad) // + : base(payLoad) { } } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/UserCreatedEvent.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/UserCreatedEvent.cs index 6ad04a5d..e14681a3 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/UserCreatedEvent.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/UserCreatedEvent.cs @@ -5,36 +5,9 @@ namespace NetAdmin.Domain.Events.Sys; /// /// 用户被创建事件 /// -public sealed record UserCreatedEvent : DataAbstraction, IEventSourceGeneric +public sealed record UserCreatedEvent : EventData { - /// - /// Initializes a new instance of the class. - /// - public UserCreatedEvent(UserInfoRsp data, DateTime createdTime = default, bool isConsumeOnce = false, object payload = null - , CancellationToken cancellationToken = default) - { - Data = data; - CancellationToken = cancellationToken; - CreatedTime = createdTime; - IsConsumeOnce = isConsumeOnce; - Payload = payload; - } - /// - public CancellationToken CancellationToken { get; } - - /// - public DateTime CreatedTime { get; } - - /// - public UserInfoRsp Data { get; } - - /// - public string EventId => nameof(UserCreatedEvent); - - /// - public bool IsConsumeOnce { get; } - - /// - public object Payload { get; } + public UserCreatedEvent(UserInfoRsp payLoad) // + : base(payLoad) { } } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/UserUpdatedEvent.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/UserUpdatedEvent.cs index 2eefb749..672484d1 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/UserUpdatedEvent.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/UserUpdatedEvent.cs @@ -5,36 +5,9 @@ namespace NetAdmin.Domain.Events.Sys; /// /// 用户被更新事件 /// -public sealed record UserUpdatedEvent : DataAbstraction, IEventSourceGeneric +public sealed record UserUpdatedEvent : EventData { - /// - /// Initializes a new instance of the class. - /// - public UserUpdatedEvent(UserInfoRsp data, DateTime createdTime = default, bool isConsumeOnce = false, object payload = null - , CancellationToken cancellationToken = default) - { - Data = data; - CancellationToken = cancellationToken; - CreatedTime = createdTime; - IsConsumeOnce = isConsumeOnce; - Payload = payload; - } - /// - public CancellationToken CancellationToken { get; } - - /// - public DateTime CreatedTime { get; } - - /// - public UserInfoRsp Data { get; } - - /// - public string EventId => nameof(UserUpdatedEvent); - - /// - public bool IsConsumeOnce { get; } - - /// - public object Payload { get; } + public UserUpdatedEvent(UserInfoRsp payLoad) // + : base(payLoad) { } } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/VerifyCodeCreatedEvent.cs b/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/VerifyCodeCreatedEvent.cs index f6f20c2b..08acfb81 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/VerifyCodeCreatedEvent.cs +++ b/src/backend/NetAdmin/NetAdmin.Domain/Events/Sys/VerifyCodeCreatedEvent.cs @@ -5,36 +5,9 @@ namespace NetAdmin.Domain.Events.Sys; /// /// 验证码创建事件 /// -public sealed record VerifyCodeCreatedEvent : DataAbstraction, IEventSourceGeneric +public sealed record VerifyCodeCreatedEvent : EventData { - /// - /// Initializes a new instance of the class. - /// - public VerifyCodeCreatedEvent(QueryVerifyCodeRsp data, DateTime createdTime = default, bool isConsumeOnce = false, object payload = null - , CancellationToken cancellationToken = default) - { - Data = data; - CancellationToken = cancellationToken; - CreatedTime = createdTime; - IsConsumeOnce = isConsumeOnce; - Payload = payload; - } - /// - public CancellationToken CancellationToken { get; } - - /// - public DateTime CreatedTime { get; } - - /// - public QueryVerifyCodeRsp Data { get; } - - /// - public string EventId => nameof(VerifyCodeCreatedEvent); - - /// - public bool IsConsumeOnce { get; } - - /// - public object Payload { get; } + public VerifyCodeCreatedEvent(QueryVerifyCodeRsp payLoad) // + : base(payLoad) { } } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Domain/NetAdmin.Domain.csproj b/src/backend/NetAdmin/NetAdmin.Domain/NetAdmin.Domain.csproj index 92ff1b72..8f22ef84 100644 --- a/src/backend/NetAdmin/NetAdmin.Domain/NetAdmin.Domain.csproj +++ b/src/backend/NetAdmin/NetAdmin.Domain/NetAdmin.Domain.csproj @@ -4,7 +4,7 @@ - + diff --git a/src/backend/NetAdmin/NetAdmin.Host/Extensions/ServiceCollectionExtensions.cs b/src/backend/NetAdmin/NetAdmin.Host/Extensions/ServiceCollectionExtensions.cs index ed9a3264..74bf9415 100644 --- a/src/backend/NetAdmin/NetAdmin.Host/Extensions/ServiceCollectionExtensions.cs +++ b/src/backend/NetAdmin/NetAdmin.Host/Extensions/ServiceCollectionExtensions.cs @@ -133,7 +133,11 @@ public static class ServiceCollectionExtensions /// public static IServiceCollection AddEventBus(this IServiceCollection me) { - return me.AddEventBus(builder => builder.AddSubscribers(App.Assemblies.ToArray())); + foreach (var type in App.EffectiveTypes.Where(x => typeof(IEventSubscriber).IsAssignableFrom(x) && x.IsClass && !x.IsAbstract)) { + _ = me.AddSingleton(type); + } + + return me.AddSingleton(new DefaultEventPublisher()); } /// diff --git a/src/backend/NetAdmin/NetAdmin.Host/Subscribers/SqlProfiler.cs b/src/backend/NetAdmin/NetAdmin.Host/Subscribers/SqlProfiler.cs index 77d48283..f2026f36 100644 --- a/src/backend/NetAdmin/NetAdmin.Host/Subscribers/SqlProfiler.cs +++ b/src/backend/NetAdmin/NetAdmin.Host/Subscribers/SqlProfiler.cs @@ -10,55 +10,50 @@ public sealed class SqlProfiler(ILogger logger) : IEventSubscriber /// /// Sql命令执行后 /// - [EventSubscribe(nameof(SqlCommandAfterEvent))] - public Task CommandAfterAsync(EventHandlerExecutingContext context) + [EventSubscribe] + public Task CommandAfterAsync(SqlCommandAfterEvent @event) { - var source = context.Source as SqlCommandAfterEvent; - logger.Info(source); + logger.Info(@event); return Task.CompletedTask; } /// /// Sql命令执行前 /// - [EventSubscribe(nameof(SqlCommandBeforeEvent))] - public Task CommandBeforeAsync(EventHandlerExecutingContext context) + [EventSubscribe] + public Task CommandBeforeAsync(SqlCommandBeforeEvent @event) { - var source = context.Source as SqlCommandBeforeEvent; - logger.Debug(source); + logger.Debug(@event); return Task.CompletedTask; } /// /// 种子数据插入完毕 /// - [EventSubscribe(nameof(SeedDataInsertedEvent))] - public Task SeedDataInsertedEventAsync(EventHandlerExecutingContext context) + [EventSubscribe] + public Task SeedDataInsertedEventAsync(SeedDataInsertedEvent @event) { - var source = context.Source as SeedDataInsertedEvent; - logger.Info(source); + logger.Info(@event); return Task.CompletedTask; } /// /// 同步数据库结构之后 /// - [EventSubscribe(nameof(SyncStructureAfterEvent))] - public Task SyncStructureAfterAsync(EventHandlerExecutingContext context) + [EventSubscribe] + public Task SyncStructureAfterAsync(SyncStructureAfterEvent @event) { - var source = context.Source as SyncStructureAfterEvent; - logger.Info(source); + logger.Info(@event); return Task.CompletedTask; } /// /// 同步数据库结构之前 /// - [EventSubscribe(nameof(SyncStructureBeforeEvent))] - public Task SyncStructureBeforeAsync(EventHandlerExecutingContext context) + [EventSubscribe] + public Task SyncStructureBeforeAsync(SyncStructureBeforeEvent @event) { - var source = context.Source as SyncStructureBeforeEvent; - logger.Info(source); + logger.Info(@event); return Task.CompletedTask; } } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/DefaultEventPublisher.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/DefaultEventPublisher.cs new file mode 100644 index 00000000..825917a0 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/DefaultEventPublisher.cs @@ -0,0 +1,34 @@ +using System.Threading.Channels; + +namespace NetAdmin.Infrastructure.EventBus; + +/// +/// 事件发布器默认实现 +/// +public sealed class DefaultEventPublisher : IEventPublisher +{ + private readonly Channel _eventChannel; + + /// + /// Initializes a new instance of the class. + /// + public DefaultEventPublisher() + { + _eventChannel = Channel.CreateUnbounded(); + _ = new TaskFactory().StartNew( // + async state => { + var subscribers = (List)state; + await foreach (var msg in _eventChannel.Reader.ReadAllAsync()) { + _ = Parallel.ForEach( // + subscribers.Where(x => x.GetParameters().FirstOrDefault()?.ParameterType == msg.GetType()) + , (x, _) => x.Invoke(App.GetService(x.DeclaringType), [msg])); + } + }, App.EffectiveTypes.Where(x => typeof(IEventSubscriber).IsAssignableFrom(x) && x.IsClass && !x.IsAbstract).SelectMany(x => x.GetMethods(BindingFlags.Instance | BindingFlags.Public).Where(y => y.IsDefined(typeof(EventSubscribeAttribute)))).ToList()); + } + + /// + public async Task PublishAsync(IEventData eventData) + { + await _eventChannel.Writer.WriteAsync(eventData).ConfigureAwait(false); + } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/EventSubscribeAttribute.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/EventSubscribeAttribute.cs new file mode 100644 index 00000000..3f70100a --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/EventSubscribeAttribute.cs @@ -0,0 +1,7 @@ +namespace NetAdmin.Infrastructure.EventBus; + +/// +/// 事件处理程序特性 +/// +[AttributeUsage(AttributeTargets.Method, Inherited = false)] +public sealed class EventSubscribeAttribute : Attribute; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventData.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventData.cs new file mode 100644 index 00000000..f9505021 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventData.cs @@ -0,0 +1,17 @@ +namespace NetAdmin.Infrastructure.EventBus; + +/// +/// 事件数据接口 +/// +public interface IEventData +{ + /// + /// 事件发生时间 + /// + public DateTime CreatedTime { get; init; } + + /// + /// 负载 + /// + public T PayLoad { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventPublisher.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventPublisher.cs new file mode 100644 index 00000000..f1bbf0c7 --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventPublisher.cs @@ -0,0 +1,12 @@ +namespace NetAdmin.Infrastructure.EventBus; + +/// +/// 事件发布器接口 +/// +public interface IEventPublisher +{ + /// + /// 发布一条消息 + /// + Task PublishAsync(IEventData eventData); +} \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventSubscriber.cs b/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventSubscriber.cs new file mode 100644 index 00000000..07e560ae --- /dev/null +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/EventBus/IEventSubscriber.cs @@ -0,0 +1,6 @@ +namespace NetAdmin.Infrastructure.EventBus; + +/// +/// 事件订阅器接口 +/// +public interface IEventSubscriber; \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.Infrastructure/NetAdmin.Infrastructure.csproj b/src/backend/NetAdmin/NetAdmin.Infrastructure/NetAdmin.Infrastructure.csproj index 643ec4ea..32ada115 100644 --- a/src/backend/NetAdmin/NetAdmin.Infrastructure/NetAdmin.Infrastructure.csproj +++ b/src/backend/NetAdmin/NetAdmin.Infrastructure/NetAdmin.Infrastructure.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/CaptchaService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/CaptchaService.cs index 97bcda0a..c46e2729 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/CaptchaService.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/CaptchaService.cs @@ -10,11 +10,6 @@ public sealed class CaptchaService : ServiceBase, ICaptchaServi private static readonly Assembly _currAsm = Assembly.GetAssembly(typeof(CaptchaService)); private static readonly string _currAsmName = _currAsm.FullName![.._currAsm.FullName.IndexOf(',')]; - /// - /// Initializes a new instance of the class. - /// - public CaptchaService() { } - /// public async Task GetCaptchaImageAsync() { diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/ApiSynchronizer.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/ApiSynchronizer.cs index 9e632179..43123381 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/ApiSynchronizer.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/ApiSynchronizer.cs @@ -10,8 +10,8 @@ public sealed class ApiSynchronizer(ILogger logger) : IEventSub /// /// 同步Api接口 /// - [EventSubscribe(nameof(SyncStructureAfterEvent))] - public async Task SyncApiAsync(EventHandlerExecutingContext _) + [EventSubscribe] + public async Task SyncApiAsync(SyncStructureAfterEvent _) { var logService = App.GetService(); await logService.SyncAsync().ConfigureAwait(false); diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/CacheCleaner.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/CacheCleaner.cs index 489f90ef..62d455d1 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/CacheCleaner.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/CacheCleaner.cs @@ -8,24 +8,16 @@ namespace NetAdmin.SysComponent.Host.Subscribers; /// public sealed class CacheCleaner : IEventSubscriber { - /// - /// Initializes a new instance of the class. - /// - public CacheCleaner() { } - /// /// 用户缓存清理 /// - [EventSubscribe(nameof(UserUpdatedEvent))] - public Task RemoveUserInfoAsync(EventHandlerExecutingContext context) + [EventSubscribe] + #pragma warning disable CA1822 + public Task RemoveUserInfoAsync(UserUpdatedEvent @event) + #pragma warning restore CA1822 { - if (context.Source is not UserUpdatedEvent userUpdatedEvent) { - return Task.CompletedTask; - } - var cache = App.GetService(); - cache.Service.UserToken = ContextUserToken.Create(userUpdatedEvent.Data.Id, userUpdatedEvent.Data.Token, userUpdatedEvent.Data.UserName - , userUpdatedEvent.Data.DeptId); + cache.Service.UserToken = ContextUserToken.Create(@event.PayLoad.Id, @event.PayLoad.Token, @event.PayLoad.UserName, @event.PayLoad.DeptId); return cache.RemoveUserInfoAsync(); } } \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/EmailCodeSender.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/EmailCodeSender.cs index a2e82ea2..c942ad1b 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/EmailCodeSender.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/EmailCodeSender.cs @@ -12,18 +12,16 @@ public sealed class EmailCodeSender(ILogger logger) : IEventSub /// /// 发送邮件 /// - [EventSubscribe(nameof(VerifyCodeCreatedEvent))] - public async Task SendEmailAsync(EventHandlerExecutingContext context) + [EventSubscribe] + public async Task SendEmailAsync(VerifyCodeCreatedEvent @event) { - if (context.Source is not VerifyCodeCreatedEvent verifyCodeCreatedEvent || - verifyCodeCreatedEvent.Data.DeviceType != VerifyCodeDeviceTypes.Email) { + if (@event.PayLoad.DeviceType != VerifyCodeDeviceTypes.Email) { return; } // 发送... var verifyCodeService = App.GetService(); - _ = await verifyCodeService.SetVerifyCodeStatusAsync( - verifyCodeCreatedEvent.Data.Adapt() with { Status = VerifyCodeStatues.Sent }) + _ = await verifyCodeService.SetVerifyCodeStatusAsync(@event.PayLoad.Adapt() with { Status = VerifyCodeStatues.Sent }) .ConfigureAwait(false); logger.Info($"{nameof(IVerifyCodeService)}.{nameof(IVerifyCodeService.SetVerifyCodeStatusAsync)} {Ln.已处理完毕}"); } diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/OperationLogger.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/OperationLogger.cs index 16c3326e..b2f11563 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/OperationLogger.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/OperationLogger.cs @@ -18,18 +18,16 @@ public sealed class OperationLogger : IEventSubscriber /// /// 保存请求日志到数据库 /// - [EventSubscribe(nameof(RequestLogEvent))] - public async Task OperationEventDbRecordAsync(EventHandlerExecutingContext context) + [EventSubscribe] + #pragma warning disable CA1822 + public async Task OperationEventDbRecordAsync(RequestLogEvent @event) + #pragma warning restore CA1822 { - if (context.Source is not RequestLogEvent operationEvent) { - return; - } - if (_requestLogs.Count > Numbers.REQUEST_LOG_BUFF_SIZE) { await WriteToDbAsync().ConfigureAwait(false); } else { - _requestLogs.Enqueue(operationEvent.Data); + _requestLogs.Enqueue(@event.PayLoad); } } @@ -81,14 +79,12 @@ public sealed class OperationLogger : IEventSubscriber /// /// 保存请求日志到数据库 /// - [EventSubscribe(nameof(RequestLogEvent))] - public async Task OperationEventDbRecordAsync(EventHandlerExecutingContext context) + [EventSubscribe] + #pragma warning disable CA1822 + public async Task OperationEventDbRecordAsync(RequestLogEvent @event) + #pragma warning restore CA1822 { - if (context.Source is not RequestLogEvent operationEvent) { - return; - } - - _ = await App.GetService().CreateAsync(operationEvent.Data).ConfigureAwait(false); + _ = await App.GetService().CreateAsync(@event.PayLoad).ConfigureAwait(false); } } #endif \ No newline at end of file diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/SmsCodeSender.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/SmsCodeSender.cs index f6a98499..5b29744a 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/SmsCodeSender.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Subscribers/SmsCodeSender.cs @@ -12,18 +12,16 @@ public sealed class SmsCodeSender(ILogger logger) : IEventSubscri /// /// 发送短信 /// - [EventSubscribe(nameof(VerifyCodeCreatedEvent))] - public async Task SendSmsAsync(EventHandlerExecutingContext context) + [EventSubscribe] + public async Task SendSmsAsync(VerifyCodeCreatedEvent @event) { - if (context.Source is not VerifyCodeCreatedEvent verifyCodeCreatedEvent || - verifyCodeCreatedEvent.Data.DeviceType != VerifyCodeDeviceTypes.Mobile) { + if (@event.PayLoad.DeviceType != VerifyCodeDeviceTypes.Mobile) { return; } // 发送... var verifyCodeService = App.GetService(); - _ = await verifyCodeService.SetVerifyCodeStatusAsync( - verifyCodeCreatedEvent.Data.Adapt() with { Status = VerifyCodeStatues.Sent }) + _ = await verifyCodeService.SetVerifyCodeStatusAsync(@event.PayLoad.Adapt() with { Status = VerifyCodeStatues.Sent }) .ConfigureAwait(false); logger.Info($"{nameof(IVerifyCodeService)}.{nameof(IVerifyCodeService.SetVerifyCodeStatusAsync)} {Ln.已处理完毕}"); }