# MAX.Notification 从本地 MediatR 14.2.0 源码抽取的通知组件,仅依赖 .NET 8,不引用任何第三方 NuGet 包。原许可声明完整保存在 LICENSE.md;源码来源和修改记录见 UPSTREAM.md。不包含请求响应、管道、流、许可证检测或容器扫描功能。移除第三方依赖不改变原源码的许可条件。 ## 定义与使用 ```csharp using MAX.Notification; public sealed record ProductChanged(int ProductId) : INotification; public sealed class RefreshCacheHandler : INotificationHandler { public Task Handle(ProductChanged notification, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // 更新缓存,或返回真正的异步业务操作。 return Task.CompletedTask; } } ``` 发布器通过标准 `IServiceProvider.GetService(typeof(IEnumerable>))` 获取处理器。调用方可自行实现此接口;组件不拥有、不释放容器及处理器。无容器实现可参考测试项目中的 TestServices。 宿主已经使用 Microsoft DI 时,可以在宿主中注册(以下扩展方法来自宿主自己的 DI 包,本项目无须引用): ```csharp services.AddTransient, RefreshCacheHandler>(); services.AddScoped(sp => new NotificationPublisher(sp)); // 在有效作用域内获取 IPublisher 后: await publisher.Publish(new ProductChanged(42), cancellationToken); ``` 宿主使用 Autofac 时: ```csharp builder.RegisterType() .As>(); builder.Register(ctx => new NotificationPublisher( new AutofacServiceProvider(ctx.Resolve()))) .As().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 支持保证。 ## 验证 ```powershell 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);同步基类本身不检查取消。