4.0 KiB
4.0 KiB
MAX.Notification
从本地 MediatR 14.2.0 源码抽取的通知组件,仅依赖 .NET 8,不引用任何第三方 NuGet 包。原许可声明完整保存在 LICENSE.md;源码来源和修改记录见 UPSTREAM.md。不包含请求响应、管道、流、许可证检测或容器扫描功能。移除第三方依赖不改变原源码的许可条件。
定义与使用
using MAX.Notification;
public sealed record ProductChanged(int ProductId) : INotification;
public sealed class RefreshCacheHandler : INotificationHandler<ProductChanged>
{
public Task Handle(ProductChanged notification, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
// 更新缓存,或返回真正的异步业务操作。
return Task.CompletedTask;
}
}
发布器通过标准 IServiceProvider.GetService(typeof(IEnumerable<INotificationHandler<T>>)) 获取处理器。调用方可自行实现此接口;组件不拥有、不释放容器及处理器。无容器实现可参考测试项目中的 TestServices。
宿主已经使用 Microsoft DI 时,可以在宿主中注册(以下扩展方法来自宿主自己的 DI 包,本项目无须引用):
services.AddTransient<INotificationHandler<ProductChanged>, RefreshCacheHandler>();
services.AddScoped<IPublisher>(sp => new NotificationPublisher(sp));
// 在有效作用域内获取 IPublisher 后:
await publisher.Publish(new ProductChanged(42), cancellationToken);
宿主使用 Autofac 时:
builder.RegisterType<RefreshCacheHandler>()
.As<INotificationHandler<ProductChanged>>();
builder.Register(ctx => new NotificationPublisher(
new AutofacServiceProvider(ctx.Resolve<ILifetimeScope>())))
.As<IPublisher>().InstancePerLifetimeScope();
上述 Autofac 示例需要宿主已有 Autofac.Extensions.DependencyInjection,或者宿主自己实现 IServiceProvider 适配器。不要把捕获短期作用域的发布器注册为单例。
行为与边界
- 默认 ForeachAwaitPublisher:按容器返回顺序逐个等待;Handler 抛异常或返回取消任务后停止,已完成的操作不会回滚。可实现 INotificationPublisher 自定义分发策略。
- 并发策略:构造时传入 new MAX.Notification.NotificationPublishers.TaskWhenAllPublisher()。使用原版 Task.WhenAll 实现;Handler 同步抛异常会中断后续枚举,已启动任务不会由此次调用统一等待。返回失败 Task 则会继续启动其他 Handler 并等待全部完成。没有 Task.Run,不保证运行在后台线程,不应并发共享非线程安全资源。
- 按通知实际运行时类型解析;不自动查找基类通知处理器,是否支持逆变解析取决于容器。
- 一次发布内相同处理器实际类型只执行第一个实例;不同类型各执行一次。这也会合并同类型但不同配置的实例。
- 无处理器时成功返回。每次发布重新解析,只缓存类型适配器,不缓存处理器或页面实例。
- 取消行为与原版一致:只传递原始 CancellationToken,发布器不主动检查取消。Handler 应自行检查或把令牌传入异步操作;没有 Handler 时,已取消的令牌不会使发布失败。
- 无消息去重、持久化、重试、事务、跨进程通信或 UI 线程调度。重复 Publish 仍会重复执行。
- 页面关闭不会自动影响 DI 中的处理器;业务 Handler 应与页面生命周期解耦。
- 使用运行时泛型反射构建适配器;当前未提供 NativeAOT / trimming 支持保证。
验证
dotnet build Source/Core/MAX.Notification/MAX.Notification.csproj -c Release
dotnet run --project Tests/MAX.Notification.SmokeTests/MAX.Notification.SmokeTests.csproj -c Release
测试项目同样不依赖第三方包,覆盖类型分发、重复处理器、重新解析、空处理器、输入校验、异常、顺序/并发及取消。
支持继承 NotificationHandler 实现同步处理器,覆写 protected Handle(notification);同步基类本身不检查取消。