mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-24 20:34:29 +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>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Mediator.Abstractions" Version="3.0.1"/>
|
<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>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -78,6 +78,14 @@ public interface IArchitecture : IAsyncInitializable
|
|||||||
/// <param name="onCreated">工具实例创建后的回调函数,可为null</param>
|
/// <param name="onCreated">工具实例创建后的回调函数,可为null</param>
|
||||||
void RegisterUtility<T>(Action<T>? onCreated = null) where T : class, IUtility;
|
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>
|
||||||
/// 安装架构模块
|
/// 安装架构模块
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using GFramework.Core.Abstractions.properties;
|
using GFramework.Core.Abstractions.properties;
|
||||||
|
using Mediator;
|
||||||
|
|
||||||
namespace GFramework.Core.Abstractions.architecture;
|
namespace GFramework.Core.Abstractions.architecture;
|
||||||
|
|
||||||
@ -16,4 +17,11 @@ public interface IArchitectureConfiguration
|
|||||||
/// 获取或设置架构选项,包含架构相关的配置参数
|
/// 获取或设置架构选项,包含架构相关的配置参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ArchitectureProperties ArchitectureProperties { get; set; }
|
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.rule;
|
||||||
using GFramework.Core.Abstractions.system;
|
using GFramework.Core.Abstractions.system;
|
||||||
|
using Mediator;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace GFramework.Core.Abstractions.ioc;
|
namespace GFramework.Core.Abstractions.ioc;
|
||||||
@ -71,6 +72,21 @@ public interface IIocContainer : IContextAware
|
|||||||
/// <param name="factory">创建服务实例的工厂委托函数</param>
|
/// <param name="factory">创建服务实例的工厂委托函数</param>
|
||||||
void RegisterFactory<TService>(Func<IServiceProvider, TService> factory) where TService : class;
|
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
|
#endregion
|
||||||
|
|
||||||
#region Get Methods
|
#region Get Methods
|
||||||
|
|||||||
@ -13,10 +13,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="LanguageExt.Core" Version="4.4.9"/>
|
<PackageReference Include="LanguageExt.Core" Version="4.4.9"/>
|
||||||
<PackageReference Include="Mediator.Abstractions" Version="3.0.1"/>
|
<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"/>
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -10,7 +10,6 @@ using GFramework.Core.Abstractions.utility;
|
|||||||
using GFramework.Core.environment;
|
using GFramework.Core.environment;
|
||||||
using GFramework.Core.extensions;
|
using GFramework.Core.extensions;
|
||||||
using GFramework.Core.logging;
|
using GFramework.Core.logging;
|
||||||
using Mediator;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using IDisposable = GFramework.Core.Abstractions.lifecycle.IDisposable;
|
using IDisposable = GFramework.Core.Abstractions.lifecycle.IDisposable;
|
||||||
|
|
||||||
@ -30,6 +29,17 @@ public abstract class Architecture(
|
|||||||
{
|
{
|
||||||
#region Module Management
|
#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>
|
||||||
/// 安装架构模块
|
/// 安装架构模块
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -627,14 +637,7 @@ public abstract class Architecture(
|
|||||||
// 为服务设置上下文
|
// 为服务设置上下文
|
||||||
Services.SetContext(_context);
|
Services.SetContext(_context);
|
||||||
// 添加 Mediator
|
// 添加 Mediator
|
||||||
Container.Services.AddMediator(options =>
|
Container.RegisterMediator(Configuration.Configurator);
|
||||||
{
|
|
||||||
options.Namespace = "GFramework.Core.Mediator";
|
|
||||||
options.ServiceLifetime = ServiceLifetime.Singleton;
|
|
||||||
options.GenerateTypesAsInternal = true;
|
|
||||||
options.NotificationPublisherType = typeof(ForeachAwaitPublisher);
|
|
||||||
});
|
|
||||||
|
|
||||||
// === 用户 Init ===
|
// === 用户 Init ===
|
||||||
_logger.Debug("Calling user Init()");
|
_logger.Debug("Calling user Init()");
|
||||||
Init();
|
Init();
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
using GFramework.Core.Abstractions.logging;
|
using GFramework.Core.Abstractions.logging;
|
||||||
using GFramework.Core.Abstractions.properties;
|
using GFramework.Core.Abstractions.properties;
|
||||||
using GFramework.Core.logging;
|
using GFramework.Core.logging;
|
||||||
|
using Mediator;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace GFramework.Core.architecture;
|
namespace GFramework.Core.architecture;
|
||||||
|
|
||||||
@ -32,4 +34,17 @@ public sealed class ArchitectureConfiguration : IArchitectureConfiguration
|
|||||||
AllowLateRegistration = false,
|
AllowLateRegistration = false,
|
||||||
StrictPhaseValidation = true
|
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.Abstractions.system;
|
||||||
using GFramework.Core.logging;
|
using GFramework.Core.logging;
|
||||||
using GFramework.Core.rule;
|
using GFramework.Core.rule;
|
||||||
|
using Mediator;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace GFramework.Core.ioc;
|
namespace GFramework.Core.ioc;
|
||||||
@ -24,12 +25,10 @@ public class MicrosoftDiContainer(IServiceCollection? serviceCollection = null)
|
|||||||
/// <exception cref="InvalidOperationException">当容器已冻结时抛出</exception>
|
/// <exception cref="InvalidOperationException">当容器已冻结时抛出</exception>
|
||||||
private void ThrowIfFrozen()
|
private void ThrowIfFrozen()
|
||||||
{
|
{
|
||||||
if (_frozen)
|
if (!_frozen) return;
|
||||||
{
|
const string errorMsg = "MicrosoftDiContainer is frozen";
|
||||||
const string errorMsg = "MicrosoftDiContainer is frozen";
|
_logger.Error(errorMsg);
|
||||||
_logger.Error(errorMsg);
|
throw new InvalidOperationException(errorMsg);
|
||||||
throw new InvalidOperationException(errorMsg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -241,6 +240,57 @@ public class MicrosoftDiContainer(IServiceCollection? serviceCollection = null)
|
|||||||
Services.AddSingleton(factory);
|
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
|
#endregion
|
||||||
|
|
||||||
#region Get
|
#region Get
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user