105040 Add 增加事件机制

This commit is contained in:
lihanbo 2024-10-31 11:41:49 +08:00
parent 6d135ba074
commit f26ea7288b
8 changed files with 196 additions and 2 deletions

View File

@ -28,6 +28,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LFlow.InternalEventBus\LFlow.InternalEventBus.csproj" />
<ProjectReference Include="..\LFlow.Middleware\LFlow.Middleware.csproj" />
</ItemGroup>

View File

@ -1,5 +1,7 @@
using LFlow.Base.Interfaces;
using LFlow.Base.Utils;
using LFlow.InternalEventBus;
using LFlow.Middleware;
using LFlow.Middleware.Register;
using Serilog;
@ -35,7 +37,11 @@ public static class Program
Log.Logger.Information("LoadSubService");
builder.Services.LoadSubService();
// 注册中间件
builder.Services.RegisterMiddlewares(App.SubServiceAssembly);
builder.Services.AddInternalEventBus(App.SubServiceAssembly);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHttpContextAccessor();
@ -104,14 +110,16 @@ public static class Program
}
// 在启动后调用Sqlsugar进行CodeFirst
// 挂载启动后事件
app.Services.GetRequiredService<IHostApplicationLifetime>().ApplicationStarted.Register(() =>
app.Services.GetRequiredService<IHostApplicationLifetime>().ApplicationStarted.Register(async () =>
{
Log.Logger.Information("ApplicationStarted");
CodeFirst.InitTable();
await InternalEventBus.InternalEventBus.Publish("Init", "ApplicationStarted");
});
// 启用自定义中间件
app.UseLFlowMiddleware();
// 启用内部事件总线
app.UseInternalEventBus();
// 启用缓存
app.UseResponseCaching();
// 启用压缩

View File

@ -0,0 +1,15 @@
namespace LFlow.InternalEventBus.Interface
{
public interface IInternalEventSubscriber
{
int Priority { get; }
string EventName { get; }
/// <summary>
/// 时间处理,返回是否处理成功
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
Task<bool> Handle(object data);
}
}

View File

@ -0,0 +1,55 @@
using LFlow.InternalEventBus.Interface;
using System.Collections.Concurrent;
namespace LFlow.InternalEventBus
{
public class InternalEventBus
{
private static readonly ConcurrentDictionary<string, List<IInternalEventSubscriber>> _eventSubscriberDict = new();
/// <summary>
/// 注册事件
/// </summary>
/// <param name="eventName"></param>
/// <param name="subscriber"></param>
public static void Register(string eventName, IInternalEventSubscriber subscriber)
{
if (!_eventSubscriberDict.ContainsKey(eventName))
{
_eventSubscriberDict.TryAdd(eventName, []);
}
_eventSubscriberDict[eventName].Add(subscriber);
}
/// <summary>
/// 取消注册事件
/// </summary>
/// <param name="eventName"></param>
/// <param name="subscriber"></param>
public static void UnRegister(string eventName, IInternalEventSubscriber subscriber)
{
if (_eventSubscriberDict.ContainsKey(eventName))
{
_eventSubscriberDict[eventName].Remove(subscriber);
}
}
/// <summary>
/// 发布事件
/// </summary>
/// <param name="eventName"></param>
/// <param name="data"></param>
/// <returns></returns>
public static async Task Publish(string eventName, object data)
{
if (_eventSubscriberDict.ContainsKey(eventName))
{
foreach (var subscriber in _eventSubscriberDict[eventName].OrderBy(i => i.Priority))
{
var isContinue = await subscriber.Handle(data);
if (!isContinue)
{
return;
}
}
}
}
}
}

View File

@ -0,0 +1,66 @@
using LFlow.InternalEventBus.Interface;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Concurrent;
using System.Reflection;
namespace LFlow.InternalEventBus
{
public static class InternalEventBusExtensions
{
private static readonly ConcurrentDictionary<Type, IInternalEventSubscriber> _eventSubscribers = new();
private static readonly ConcurrentBag<Type> _eventSubscriberTypes = [];
/// <summary>
/// 添加事件订阅服务
/// </summary>
/// <param name="services"></param>
/// <param name="assemblies"></param>
public static void AddInternalEventBus(this IServiceCollection services, List<Assembly> assemblies)
{
assemblies?.ForEach(assembly =>
{
var types = assembly.GetTypes().ToList();
foreach (var type in types)
{
if (type.GetInterface(nameof(IInternalEventSubscriber)) != null)
{
services.AddSingleton(type);
_eventSubscriberTypes.Add(type);
}
}
});
}
/// <summary>
/// 构建事件对象列表
/// </summary>
/// <param name="app"></param>
private static void BuildInternalEventBusServiceProvider(this IApplicationBuilder app)
{
var serviceProvider = app.ApplicationServices;
_eventSubscriberTypes.ToList().ForEach(type =>
{
if (serviceProvider.GetService(type) is IInternalEventSubscriber subscriber)
_eventSubscribers.TryAdd(type, subscriber);
});
}
/// <summary>
/// 启用内部事件
/// </summary>
/// <param name="app"></param>
public static void UseInternalEventBus(this IApplicationBuilder app)
{
// build serviceProvider and eventSubscribers
app.BuildInternalEventBusServiceProvider();
// sort by priority
var orderedSubscribers = _eventSubscribers.Values.OrderBy(t => t?.Priority ?? 0).ToList();
orderedSubscribers.ForEach(subscriber =>
{
if (subscriber is IInternalEventSubscriber eventSubscriber)
{
InternalEventBus.Register(eventSubscriber.EventName, eventSubscriber);
}
});
}
}
}

View File

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputPath>../LFlow_Bin/</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.AspNetCore.Http.Abstractions">
<HintPath>..\..\..\..\..\.nuget\microsoft.aspnetcore.http.abstractions\2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions">
<HintPath>..\..\..\..\..\.nuget\microsoft.extensions.dependencyinjection.abstractions\8.0.2\lib\net8.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="Enum\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,17 @@
using LFlow.InternalEventBus.Interface;
using Serilog;
namespace LFlow.UserManagement
{
internal class InitEventSubscriber(ILogger logger) : IInternalEventSubscriber
{
public int Priority => 1;
public string EventName => "Init";
public Task<bool> Handle(object data)
{
logger.Information($"Init event received. data => {data}");
return Task.FromResult(true);
}
}
}

View File

@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LFlow.UserManagement", "LFl
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LFlow.Middleware", "LFlow.Middleware\LFlow.Middleware.csproj", "{5BFD207E-28B3-40B8-94DF-1723C6A4424B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LFlow.InternalEventBus", "LFlow.InternalEventBus\LFlow.InternalEventBus.csproj", "{72CB0C72-9725-43A5-882D-3E93FD1F8706}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -39,6 +41,10 @@ Global
{5BFD207E-28B3-40B8-94DF-1723C6A4424B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5BFD207E-28B3-40B8-94DF-1723C6A4424B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5BFD207E-28B3-40B8-94DF-1723C6A4424B}.Release|Any CPU.Build.0 = Release|Any CPU
{72CB0C72-9725-43A5-882D-3E93FD1F8706}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72CB0C72-9725-43A5-882D-3E93FD1F8706}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72CB0C72-9725-43A5-882D-3E93FD1F8706}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72CB0C72-9725-43A5-882D-3E93FD1F8706}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE