NotificationPublisher.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. using System;
  2. using System.Linq;
  3. using System.Threading.Tasks;
  4. using Abp.BackgroundJobs;
  5. using Abp.Collections.Extensions;
  6. using Abp.Dependency;
  7. using Abp.Domain.Entities;
  8. using Abp.Domain.Uow;
  9. using Abp.Extensions;
  10. using Abp.Json;
  11. using Abp.Runtime.Session;
  12. namespace Abp.Notifications
  13. {
  14. /// <summary>
  15. /// Implements <see cref="INotificationPublisher"/>.
  16. /// </summary>
  17. public class NotificationPublisher : AbpServiceBase, INotificationPublisher, ITransientDependency
  18. {
  19. public const int MaxUserCountToDirectlyDistributeANotification = 5;
  20. /// <summary>
  21. /// Indicates all tenants.
  22. /// </summary>
  23. public static int[] AllTenants
  24. {
  25. get
  26. {
  27. return new[] { NotificationInfo.AllTenantIds.To<int>() };
  28. }
  29. }
  30. /// <summary>
  31. /// Reference to ABP session.
  32. /// </summary>
  33. public IAbpSession AbpSession { get; set; }
  34. private readonly INotificationStore _store;
  35. private readonly IBackgroundJobManager _backgroundJobManager;
  36. private readonly INotificationConfiguration _notificationConfiguration;
  37. private readonly IGuidGenerator _guidGenerator;
  38. private readonly IIocResolver _iocResolver;
  39. /// <summary>
  40. /// Initializes a new instance of the <see cref="NotificationPublisher"/> class.
  41. /// </summary>
  42. public NotificationPublisher(
  43. INotificationStore store,
  44. IBackgroundJobManager backgroundJobManager,
  45. INotificationConfiguration notificationConfiguration,
  46. IGuidGenerator guidGenerator,
  47. IIocResolver iocResolver)
  48. {
  49. _store = store;
  50. _backgroundJobManager = backgroundJobManager;
  51. _notificationConfiguration = notificationConfiguration;
  52. _guidGenerator = guidGenerator;
  53. _iocResolver = iocResolver;
  54. AbpSession = NullAbpSession.Instance;
  55. }
  56. //Create EntityIdentifier includes entityType and entityId.
  57. [UnitOfWork]
  58. public virtual async Task PublishAsync(
  59. string notificationName,
  60. NotificationData data = null,
  61. EntityIdentifier entityIdentifier = null,
  62. NotificationSeverity severity = NotificationSeverity.Info,
  63. UserIdentifier[] userIds = null,
  64. UserIdentifier[] excludedUserIds = null,
  65. int?[] tenantIds = null)
  66. {
  67. if (notificationName.IsNullOrEmpty())
  68. {
  69. throw new ArgumentException("NotificationName can not be null or whitespace!", "notificationName");
  70. }
  71. if (!tenantIds.IsNullOrEmpty() && !userIds.IsNullOrEmpty())
  72. {
  73. throw new ArgumentException("tenantIds can be set only if userIds is not set!", "tenantIds");
  74. }
  75. if (tenantIds.IsNullOrEmpty() && userIds.IsNullOrEmpty())
  76. {
  77. tenantIds = new[] { AbpSession.TenantId };
  78. }
  79. var notificationInfo = new NotificationInfo(_guidGenerator.Create())
  80. {
  81. NotificationName = notificationName,
  82. EntityTypeName = entityIdentifier == null ? null : entityIdentifier.Type.FullName,
  83. EntityTypeAssemblyQualifiedName = entityIdentifier == null ? null : entityIdentifier.Type.AssemblyQualifiedName,
  84. EntityId = entityIdentifier == null ? null : entityIdentifier.Id.ToJsonString(),
  85. Severity = severity,
  86. UserIds = userIds.IsNullOrEmpty() ? null : userIds.Select(uid => uid.ToUserIdentifierString()).JoinAsString(","),
  87. ExcludedUserIds = excludedUserIds.IsNullOrEmpty() ? null : excludedUserIds.Select(uid => uid.ToUserIdentifierString()).JoinAsString(","),
  88. TenantIds = tenantIds.IsNullOrEmpty() ? null : tenantIds.JoinAsString(","),
  89. Data = data == null ? null : data.ToJsonString(),
  90. DataTypeName = data == null ? null : data.GetType().AssemblyQualifiedName
  91. };
  92. await _store.InsertNotificationAsync(notificationInfo);
  93. await CurrentUnitOfWork.SaveChangesAsync(); //To get Id of the notification
  94. if (userIds != null && userIds.Length <= MaxUserCountToDirectlyDistributeANotification)
  95. {
  96. //We can directly distribute the notification since there are not much receivers
  97. foreach (var notificationDistributorType in _notificationConfiguration.Distributers)
  98. {
  99. using (var notificationDistributer = _iocResolver.ResolveAsDisposable<INotificationDistributer>(notificationDistributorType))
  100. {
  101. await notificationDistributer.Object.DistributeAsync(notificationInfo.Id);
  102. }
  103. }
  104. }
  105. else
  106. {
  107. //We enqueue a background job since distributing may get a long time
  108. await _backgroundJobManager.EnqueueAsync<NotificationDistributionJob, NotificationDistributionJobArgs>(
  109. new NotificationDistributionJobArgs(
  110. notificationInfo.Id
  111. )
  112. );
  113. }
  114. }
  115. }
  116. }