CrestApps.Queues 1.10.0-preview-0029

This is a prerelease version of CrestApps.Queues.
dotnet add package CrestApps.Queues --version 1.10.0-preview-0029
                    
NuGet\Install-Package CrestApps.Queues -Version 1.10.0-preview-0029
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CrestApps.Queues" Version="1.10.0-preview-0029" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CrestApps.Queues" Version="1.10.0-preview-0029" />
                    
Directory.Packages.props
<PackageReference Include="CrestApps.Queues" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CrestApps.Queues --version 1.10.0-preview-0029
                    
#r "nuget: CrestApps.Queues, 1.10.0-preview-0029"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CrestApps.Queues@1.10.0-preview-0029
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CrestApps.Queues&version=1.10.0-preview-0029&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=CrestApps.Queues&version=1.10.0-preview-0029&prerelease
                    
Install as a Cake Tool

Queues

This module offers essential services for queuing elements and processing them in the background. It proves particularly useful when there is a need to queue tasks such as notifications or emails for background processing.

Since this module focuses solely on providing core services, it is marked with the EnabledByDependencyOnly flag, making it available on demand.

To utilize this module, you can create an OrchardCore module and add a dependency on CrestApps.Queues feature. Additionally, to handle your queue items, you need to implement the IQueueElementProcessor, which is responsible for processing the queued elements.

For queuing elements, utilize the IQueueStore interface.

Notification Processor

If both the OrchardCore.Notifications feature and the CrestApps.Queues modules are activated simultaneously, a default processor for handling notifications is automatically registered.

To customize the recipient of the notification based on the provided content-item, all you need to do is implement the INotificationQueueUserProvider provider.

!! Note Please note that in the absence of an implementation for INotificationQueueUserProvider, the notifications will be disregarded and not sent.

Example of implementing an Email Queue Processor

In this example, we employ a retry logic of 5 attempts in this instance to enable the processing of the queue element before considering it abandoned.

public sealed class EmailQueueProcessor : IQueueElementProcessor
{
    /// <summary>
    /// Sets the max attempts to send the email before abandon the element.
    /// </summary>
    private const int _maxAttempts = 5;

    private readonly IEmailService _emailService;

    private IEnumerable<User> _users;

    public EmailQueueProcessor(IEmailService emailService)
    {
        _emailService = emailService;
    }

    public bool CanHandle(string queueName)
    {
        return queueName == "Email";
    }

    public Task<bool> IsProcessableAsync(QueueElement element)
    {
        return Task.FromResult(element.FailedCounter < _maxAttempts);
    }

    public async Task ProcessAsync(QueueElementProcessingContext context)
    {
        foreach (var item in context.Elements)
        {
            var message = item.As<MailMessage>();

            if(message == null)
            {
                // No message was found on the queue element.
                item.IsRemovable = true;

                continue;
            }

            var result = await _emailService.SendAsync(message);

            item.IsProcessed = result.Succeeded;
        }
    }
}

Example of creating Email Queue elements using a Content Type Handler.

In this particular scenario, we make the assumption that there exists a content type called ContactFormEntry which is completed by a site visitor. Our objective is to enqueue an email for sending it to the site owner.

public sealed class ContactFormContentType : ContentHandlerBase
{
    private const string _contentType = "ContactFormEntry";

    private readonly IQueueStore _queueStore;

    public ContactFormContentType(IQueueStore queueStore)
    {
        _queueStore = queueStore;
    }

    public override Task PublishedAsync(PublishContentContext context)
    {
        if(context.PublishingItem.ContentType != _contentType)
        {
            return Task.CompletedTask;
        }

        return AddOrUpdateNotificationQueueAsync(context.PublishingItem);
    }

    public override Task UnpublishedAsync(PublishContentContext context)
    {
        if (context.PublishingItem.ContentType != _contentType)
        {
            return Task.CompletedTask;
        }

        return RemoveNotificationQueueAsync(context.PublishingItem);
    }

    public override Task RemovedAsync(RemoveContentContext context)
    {
        if (context.ContentItem.ContentType != _contentType)
        {
            return Task.CompletedTask;
        }

        return RemoveNotificationQueueAsync(context.ContentItem);
    }

    private async Task AddOrUpdateNotificationQueueAsync(ContentItem contentItem)
    {
        var queueItems = await _queueStore.GetCorrelationAsync(contentItem.ContentItemId);

        // Get event date and add minuts to it.
        var queueItem = queueItems.FirstOrDefault(x => x.QueueName == "Email")
            ?? new QueueElement()
        {
            CorrelationId = contentItem.ContentItemId,
            QueueName = "Email",
        };

        // The Mail info will come from the contact form entry or other sources.
        var message = new MailMessage()
        {
            Subject = contentItem.Content.ContactFormEntry.Subject.Text,
            Body = contentItem.Content.ContactFormEntry.Message.Text,
            To = "owner@example.com",
        };

        queueItem.Put(message);

        await _queueStore.SaveAsync(queueItem);

        await _queueStore.SaveChangesAsync();
    }

    private async Task RemoveNotificationQueueAsync(ContentItem contentItem)
    {
        var queueItems = await _queueStore.GetCorrelationAsync(contentItem.ContentItemId);

        foreach (var queueItem in queueItems)
        {
            if (queueItem.QueueName != "Email")
            {
                continue;
            }

            await _queueStore.DeleteAsync(queueItem);
        }

        await _queueStore.SaveChangesAsync();
    }
}
Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.10.0-preview-0029 289 8/14/2025
1.10.0-preview-0028 252 6/20/2025
1.10.0-preview-0027 567 1/9/2025
1.10.0-preview-0026 116 1/9/2025
1.10.0-preview-0025 169 1/3/2025
1.10.0-preview-0024 146 1/2/2025
1.10.0-preview-0023 714 9/9/2024
1.10.0-preview-0022 177 8/26/2024
1.10.0-preview-0021 116 8/26/2024
1.10.0-preview-0020 168 8/7/2024
1.10.0-preview-0007 150 7/22/2024
1.10.0-preview-0006 185 6/10/2024
1.10.0-preview-0005 146 6/6/2024
1.10.0-preview-0004 136 6/5/2024
1.10.0-preview-0003 251 5/7/2024
1.10.0-preview-0002 184 3/8/2024
1.10.0-preview-0001 133 3/7/2024
1.9.0 592 1/17/2024
1.1.0 176 1/17/2024
1.0.8 410 9/19/2023
1.0.7 367 8/16/2023
1.0.6 244 8/14/2023
1.0.5 259 8/4/2023
1.0.4 254 8/1/2023
1.0.3 229 8/1/2023
1.0.2 217 8/1/2023
1.0.1 305 7/12/2023
1.0.0 290 7/12/2023