mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
feat(core): 集成Mediator框架并添加CQRS行为支持
- 移除直接的Mediator包依赖,改用Source Generator方式集成 - 添加RegisterMediator方法用于配置Mediator框架 - 添加RegisterMediatorBehavior方法用于注册管道行为 - 实现LoggingBehavior用于记录CQRS请求处理日志 - 实现PerformanceBehavior用于监控请求执行性能 - 更新架构配置以支持Mediator自定义配置 - 优化容器冻结检查的代码结构
This commit is contained in:
parent
b7efe0cac4
commit
91c9163312
@ -26,5 +26,9 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mediator.Abstractions" Version="3.0.1"/>
|
||||
<PackageReference Include="Mediator.SourceGenerator" Version="3.0.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@ -78,6 +78,14 @@ public interface IArchitecture : IAsyncInitializable
|
||||
/// <param name="onCreated">工具实例创建后的回调函数,可为null</param>
|
||||
void RegisterUtility<T>(Action<T>? onCreated = null) where T : class, IUtility;
|
||||
|
||||
/// <summary>
|
||||
/// 注册中介行为管道
|
||||
/// 用于配置Mediator框架的行为拦截和处理逻辑
|
||||
/// </summary>
|
||||
/// <typeparam name="TBehavior">行为类型,必须是引用类型</typeparam>
|
||||
void RegisterMediatorBehavior<TBehavior>()
|
||||
where TBehavior : class;
|
||||
|
||||
/// <summary>
|
||||
/// 安装架构模块
|
||||
/// </summary>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using GFramework.Core.Abstractions.properties;
|
||||
using Mediator;
|
||||
|
||||
namespace GFramework.Core.Abstractions.architecture;
|
||||
|
||||
@ -16,4 +17,11 @@ public interface IArchitectureConfiguration
|
||||
/// 获取或设置架构选项,包含架构相关的配置参数
|
||||
/// </summary>
|
||||
ArchitectureProperties ArchitectureProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置Mediator配置委托
|
||||
/// 用于自定义Mediator框架的配置选项
|
||||
/// </summary>
|
||||
/// <returns>配置Mediator选项的委托函数,可为null</returns>
|
||||
Action<MediatorOptions>? Configurator { get; set; }
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using GFramework.Core.Abstractions.rule;
|
||||
using GFramework.Core.Abstractions.system;
|
||||
using Mediator;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace GFramework.Core.Abstractions.ioc;
|
||||
@ -71,6 +72,21 @@ public interface IIocContainer : IContextAware
|
||||
/// <param name="factory">创建服务实例的工厂委托函数</param>
|
||||
void RegisterFactory<TService>(Func<IServiceProvider, TService> factory) where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// 注册中介行为管道
|
||||
/// 用于配置Mediator框架的行为拦截和处理逻辑
|
||||
/// </summary>
|
||||
/// <typeparam name="TBehavior">行为类型,必须是引用类型</typeparam>
|
||||
void RegisterMediatorBehavior<TBehavior>()
|
||||
where TBehavior : class;
|
||||
|
||||
/// <summary>
|
||||
/// 注册并配置Mediator框架
|
||||
/// 提供自定义配置选项来调整Mediator的行为
|
||||
/// </summary>
|
||||
/// <param name="configurator">可选的配置委托函数,用于自定义Mediator选项</param>
|
||||
void RegisterMediator(Action<MediatorOptions>? configurator = null);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get Methods
|
||||
|
||||
@ -13,10 +13,6 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LanguageExt.Core" Version="4.4.9"/>
|
||||
<PackageReference Include="Mediator.Abstractions" Version="3.0.1"/>
|
||||
<PackageReference Include="Mediator.SourceGenerator" Version="3.0.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@ -10,7 +10,6 @@ using GFramework.Core.Abstractions.utility;
|
||||
using GFramework.Core.environment;
|
||||
using GFramework.Core.extensions;
|
||||
using GFramework.Core.logging;
|
||||
using Mediator;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using IDisposable = GFramework.Core.Abstractions.lifecycle.IDisposable;
|
||||
|
||||
@ -30,6 +29,17 @@ public abstract class Architecture(
|
||||
{
|
||||
#region Module Management
|
||||
|
||||
/// <summary>
|
||||
/// 注册中介行为管道
|
||||
/// 用于配置Mediator框架的行为拦截和处理逻辑
|
||||
/// </summary>
|
||||
/// <typeparam name="TBehavior">行为类型,必须是引用类型</typeparam>
|
||||
public void RegisterMediatorBehavior<TBehavior>() where TBehavior : class
|
||||
{
|
||||
_logger.Debug($"Registering mediator behavior: {typeof(TBehavior).Name}");
|
||||
Container.RegisterPlurality<TBehavior>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安装架构模块
|
||||
/// </summary>
|
||||
@ -627,14 +637,7 @@ public abstract class Architecture(
|
||||
// 为服务设置上下文
|
||||
Services.SetContext(_context);
|
||||
// 添加 Mediator
|
||||
Container.Services.AddMediator(options =>
|
||||
{
|
||||
options.Namespace = "GFramework.Core.Mediator";
|
||||
options.ServiceLifetime = ServiceLifetime.Singleton;
|
||||
options.GenerateTypesAsInternal = true;
|
||||
options.NotificationPublisherType = typeof(ForeachAwaitPublisher);
|
||||
});
|
||||
|
||||
Container.RegisterMediator(Configuration.Configurator);
|
||||
// === 用户 Init ===
|
||||
_logger.Debug("Calling user Init()");
|
||||
Init();
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
using GFramework.Core.Abstractions.logging;
|
||||
using GFramework.Core.Abstractions.properties;
|
||||
using GFramework.Core.logging;
|
||||
using Mediator;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace GFramework.Core.architecture;
|
||||
|
||||
@ -32,4 +34,17 @@ public sealed class ArchitectureConfiguration : IArchitectureConfiguration
|
||||
AllowLateRegistration = false,
|
||||
StrictPhaseValidation = true
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置Mediator配置委托
|
||||
/// 用于自定义Mediator框架的配置选项
|
||||
/// </summary>
|
||||
/// <returns>配置Mediator选项的委托函数,可为null</returns>
|
||||
public Action<MediatorOptions>? Configurator { get; set; } = options =>
|
||||
{
|
||||
options.Namespace = "GFramework.Core.Mediator";
|
||||
options.ServiceLifetime = ServiceLifetime.Singleton;
|
||||
options.GenerateTypesAsInternal = true;
|
||||
options.NotificationPublisherType = typeof(ForeachAwaitPublisher);
|
||||
};
|
||||
}
|
||||
59
GFramework.Core/cqrs/behaviors/LoggingBehavior.cs
Normal file
59
GFramework.Core/cqrs/behaviors/LoggingBehavior.cs
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2026 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using GFramework.Core.Abstractions.logging;
|
||||
using GFramework.Core.logging;
|
||||
using Mediator;
|
||||
|
||||
namespace GFramework.Core.cqrs.behaviors;
|
||||
|
||||
/// <summary>
|
||||
/// 日志记录行为类,用于在CQRS管道中记录请求处理的日志信息
|
||||
/// 实现IPipelineBehavior接口,为请求处理提供日志记录功能
|
||||
/// </summary>
|
||||
/// <typeparam name="TRequest">请求类型,必须实现IRequest接口</typeparam>
|
||||
/// <typeparam name="TResponse">响应类型</typeparam>
|
||||
public sealed class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
|
||||
where TRequest : IRequest<TResponse>
|
||||
{
|
||||
private readonly ILogger _logger =
|
||||
LoggerFactoryResolver.Provider.CreateLogger(nameof(LoggingBehavior<TRequest, TResponse>));
|
||||
|
||||
/// <summary>
|
||||
/// 处理请求并记录日志
|
||||
/// 在请求处理前后记录调试信息,处理异常时记录错误日志
|
||||
/// </summary>
|
||||
/// <param name="message">要处理的请求消息</param>
|
||||
/// <param name="next">下一个处理委托,用于继续管道执行</param>
|
||||
/// <param name="cancellationToken">取消令牌,用于取消操作</param>
|
||||
/// <returns>处理结果的ValueTask</returns>
|
||||
public ValueTask<TResponse> Handle(TRequest message, MessageHandlerDelegate<TRequest, TResponse> next,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var requestName = typeof(TRequest).Name;
|
||||
|
||||
_logger.Debug($"Handling {requestName}");
|
||||
|
||||
try
|
||||
{
|
||||
var response = next(message, cancellationToken);
|
||||
_logger.Debug($"Handled {requestName} successfully");
|
||||
return response;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"Error handling {requestName}", ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
59
GFramework.Core/cqrs/behaviors/PerformanceBehavior.cs
Normal file
59
GFramework.Core/cqrs/behaviors/PerformanceBehavior.cs
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2026 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System.Diagnostics;
|
||||
using GFramework.Core.Abstractions.logging;
|
||||
using GFramework.Core.logging;
|
||||
using Mediator;
|
||||
|
||||
namespace GFramework.Core.cqrs.behaviors;
|
||||
|
||||
/// <summary>
|
||||
/// 性能监控行为类,用于监控CQRS请求的执行时间
|
||||
/// 实现IPipelineBehavior接口,检测并记录执行时间过长的请求
|
||||
/// </summary>
|
||||
/// <typeparam name="TRequest">请求类型,必须实现IRequest接口</typeparam>
|
||||
/// <typeparam name="TResponse">响应类型</typeparam>
|
||||
public sealed class PerformanceBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
|
||||
where TRequest : IRequest<TResponse>
|
||||
{
|
||||
private readonly ILogger _logger =
|
||||
LoggerFactoryResolver.Provider.CreateLogger(nameof(PerformanceBehavior<TRequest, TResponse>));
|
||||
|
||||
/// <summary>
|
||||
/// 处理请求并监控执行时间
|
||||
/// 使用Stopwatch测量请求处理耗时,超过500ms时记录警告日志
|
||||
/// </summary>
|
||||
/// <param name="message">要处理的请求消息</param>
|
||||
/// <param name="next">下一个处理委托,用于继续管道执行</param>
|
||||
/// <param name="cancellationToken">取消令牌,用于取消操作</param>
|
||||
/// <returns>处理结果的ValueTask</returns>
|
||||
public ValueTask<TResponse> Handle(TRequest message, MessageHandlerDelegate<TRequest, TResponse> next,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
|
||||
var response = next(message, cancellationToken);
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
var elapsedMilliseconds = stopwatch.ElapsedMilliseconds;
|
||||
|
||||
// 只有当执行时间超过500毫秒时才记录警告日志
|
||||
if (elapsedMilliseconds <= 500) return response;
|
||||
var requestName = typeof(TRequest).Name;
|
||||
_logger.Warn($"Long Running Request: {requestName} ({elapsedMilliseconds} ms)");
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ using GFramework.Core.Abstractions.logging;
|
||||
using GFramework.Core.Abstractions.system;
|
||||
using GFramework.Core.logging;
|
||||
using GFramework.Core.rule;
|
||||
using Mediator;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace GFramework.Core.ioc;
|
||||
@ -24,12 +25,10 @@ public class MicrosoftDiContainer(IServiceCollection? serviceCollection = null)
|
||||
/// <exception cref="InvalidOperationException">当容器已冻结时抛出</exception>
|
||||
private void ThrowIfFrozen()
|
||||
{
|
||||
if (_frozen)
|
||||
{
|
||||
const string errorMsg = "MicrosoftDiContainer is frozen";
|
||||
_logger.Error(errorMsg);
|
||||
throw new InvalidOperationException(errorMsg);
|
||||
}
|
||||
if (!_frozen) return;
|
||||
const string errorMsg = "MicrosoftDiContainer is frozen";
|
||||
_logger.Error(errorMsg);
|
||||
throw new InvalidOperationException(errorMsg);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -241,6 +240,57 @@ public class MicrosoftDiContainer(IServiceCollection? serviceCollection = null)
|
||||
Services.AddSingleton(factory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册中介行为管道
|
||||
/// 用于配置Mediator框架的行为拦截和处理逻辑
|
||||
/// </summary>
|
||||
/// <typeparam name="TBehavior">行为类型,必须是引用类型</typeparam>
|
||||
public void RegisterMediatorBehavior<TBehavior>() where TBehavior : class
|
||||
{
|
||||
_lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
ThrowIfFrozen();
|
||||
|
||||
Services.AddSingleton(
|
||||
typeof(IPipelineBehavior<,>),
|
||||
typeof(TBehavior)
|
||||
);
|
||||
|
||||
_logger.Debug($"Mediator behavior registered: {typeof(TBehavior).Name}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册 Mediator(基于 Source Generator)
|
||||
/// </summary>
|
||||
/// <param name="configurator">可选的配置委托</param>
|
||||
public void RegisterMediator(Action<MediatorOptions>? configurator = null)
|
||||
{
|
||||
_lock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
ThrowIfFrozen();
|
||||
|
||||
// 添加 Mediator
|
||||
Services.AddMediator(options =>
|
||||
{
|
||||
// 用户自定义配置
|
||||
configurator?.Invoke(options);
|
||||
});
|
||||
|
||||
_logger.Info("Mediator registered with Source Generator");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_lock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user