diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishInterceptor.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishInterceptor.cs
new file mode 100644
index 000000000..27437a1b5
--- /dev/null
+++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishInterceptor.cs
@@ -0,0 +1,20 @@
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.Notifications;
+///
+/// 通知发布拦截器, 实现此接口来增加发布前的自定义检查
+///
+public interface INotificationPublishInterceptor
+{
+ ///
+ /// 拦截优先级,数值越小优先级越高
+ ///
+ int Priority { get; }
+
+ ///
+ /// 在通知发布前执行检查
+ ///
+ /// 通知信息
+ /// true-允许发布, false-阻止发布
+ Task CanPublishAsync(NotificationInfo notification);
+}
diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs
index 8bf1cc899..8e52907a7 100644
--- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs
+++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs
@@ -1,6 +1,8 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
@@ -21,6 +23,11 @@ public abstract class NotificationPublishProvider : INotificationPublishProvider
public ICancellationTokenProvider CancellationTokenProvider => ServiceProvider.LazyGetService(NullCancellationTokenProvider.Instance);
+ private IEnumerable _interceptors;
+ protected IEnumerable Interceptors =>
+ _interceptors ??= ServiceProvider.LazyGetService>()
+ ?? Enumerable.Empty();
+
public async virtual Task CanPublishAsync(NotificationInfo notification)
{
return await CanPublishAsync(notification, GetCancellationToken());
@@ -28,9 +35,23 @@ public abstract class NotificationPublishProvider : INotificationPublishProvider
public async Task PublishAsync(NotificationPublishContext context)
{
- await PublishAsync(context, GetCancellationToken());
+ var cancellationToken = GetCancellationToken();
+
+ // 通知拦截器检查
+ if (!await ExecuteInterceptorsAsync(context, cancellationToken))
+ {
+ return;
+ }
+
+ await PublishAsync(context, cancellationToken);
}
+ ///
+ /// 是否允许发布通知
+ ///
+ ///
+ ///
+ ///
protected virtual Task CanPublishAsync(
NotificationInfo notification,
CancellationToken cancellationToken = default)
@@ -38,6 +59,60 @@ public abstract class NotificationPublishProvider : INotificationPublishProvider
return Task.FromResult(true);
}
+ ///
+ /// 执行通知发布拦截器
+ ///
+ ///
+ ///
+ ///
+ protected virtual async Task ExecuteInterceptorsAsync(
+ NotificationPublishContext context,
+ CancellationToken cancellationToken = default)
+ {
+ if (context.Notification.Type == NotificationType.System ||
+ context.Notification.Type == NotificationType.ServiceCallback)
+ {
+ Logger.LogDebug(
+ "System or service callback notification {NotificationName}, skip all interceptors.",
+ context.Notification.Name);
+ return true;
+ }
+
+ if (!Interceptors.Any())
+ {
+ Logger.LogDebug("No notification publishing interceptors have been registered.");
+ return true;
+ }
+
+ var orderedInterceptors = Interceptors.OrderBy(i => i.Priority);
+
+ foreach (var interceptor in orderedInterceptors)
+ {
+ try
+ {
+ if (!await interceptor.CanPublishAsync(context.Notification))
+ {
+ var reason = string.Format("The interceptor {0} prevented the publication of the notification {1}.",
+ interceptor.GetType().Name,
+ context.Notification.Name);
+
+ context.Cancel(reason);
+
+ Logger.LogWarning(reason);
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.LogWarning(ex,
+ "An exception occurred while executing the interceptor {InterceptorType}. By default, publication is allowed.",
+ interceptor.GetType().Name);
+ }
+ }
+
+ return true;
+ }
+
protected virtual CancellationToken GetCancellationToken(CancellationToken cancellationToken = default)
{
return CancellationTokenProvider.FallbackToProvider(cancellationToken);