Kanject.Core.Queue.Abstractions
3.7.1
Prefix Reserved
See the version list below for details.
dotnet add package Kanject.Core.Queue.Abstractions --version 3.7.1
NuGet\Install-Package Kanject.Core.Queue.Abstractions -Version 3.7.1
<PackageReference Include="Kanject.Core.Queue.Abstractions" Version="3.7.1" />
<PackageVersion Include="Kanject.Core.Queue.Abstractions" Version="3.7.1" />
<PackageReference Include="Kanject.Core.Queue.Abstractions" />
paket add Kanject.Core.Queue.Abstractions --version 3.7.1
#r "nuget: Kanject.Core.Queue.Abstractions, 3.7.1"
#:package Kanject.Core.Queue.Abstractions@3.7.1
#addin nuget:?package=Kanject.Core.Queue.Abstractions&version=3.7.1
#tool nuget:?package=Kanject.Core.Queue.Abstractions&version=3.7.1
Kanject.Core.Queue.Abstractions
Provider-neutral queue contracts for Kanject services. The package contains the IQueueManager / IQueueManagerService surface for sending, receiving and acknowledging messages, the consumer and router interfaces, the MessageContext<T> envelope, queue-naming helpers, and the scheduling contract IQueueSchedulerProvider with its request and response models.
Reference it from code that sends or handles queue messages but shouldn't depend on a specific broker. The Amazon SQS implementation ships in Kanject.Core.Queue.Provider.AwsSqs.
Installation
dotnet add package Kanject.Core.Queue.Abstractions
Targets .NET 8, .NET 9 and .NET 10. Depends on Kanject.Core.
Quick start
Write application services against IQueueManagerService. The provider package registers the implementation.
using Kanject.Core.Queue.Abstractions.Interfaces;
public sealed class OrderPlaced
{
public string OrderId { get; set; } = string.Empty;
public string TenantId { get; set; } = string.Empty;
}
public sealed class CheckoutService(IQueueManagerService queues)
{
public async Task CompleteAsync(OrderPlaced order)
{
var metadata = new Dictionary<string, string> { ["tenant"] = order.TenantId };
// "orders" identifies the registered queue.
if (!await queues.EnqueueAsync("orders", order, metadata))
throw new InvalidOperationException($"Order {order.OrderId} could not be queued.");
}
}
Message types must have a public parameterless constructor, because every generic member is constrained to where TQueueMessage : new(). The SQS provider sends the metadata dictionary as SQS message attributes.
Sending, receiving and acknowledging
IQueueManager: one queue
| Member | Purpose |
|---|---|
EnqueueAsync<T>(message), EnqueueAsync<T>(message, metadata) |
Send one message, with or without metadata |
EnqueueAsync<T>(IList<T> messages), EnqueueAsync<T>(IList<(T model, Dictionary<string, string> metadata)>) |
Send a batch |
EnqueueAsync<T>(route, message) and the other route overloads |
Send a message tagged with a route for routed consumers |
EnqueueAsync(route, string message) |
Send a pre-serialized body |
DequeueAsync<T>() |
Receive a single message as MessageContext<T>? |
PoolQueueMessagesAsync<T>() |
Receive a batch of messages |
AcknowledgeAsync<T>(context), AcknowledgeAsync<T>(IEnumerable<MessageContext<T>>) |
Mark messages as processed, which removes them from the queue |
Every enqueue method returns Task<bool>: true means the provider accepted the message.
IQueueManagerService: every registered queue
IQueueManagerService exposes one IQueueManager per queue through its indexer, along with shortcuts that take the queue key as their first argument:
// Shortcut form: routeKey is the queue key.
await queues.EnqueueAsync("orders", order);
// Indexer form: reach one queue's IQueueManager, e.g. to tag a route.
await queues["order-events"].EnqueueAsync("order.created", order);
The service also defines Initialize(), which a provider uses to resolve its registered queues and create any that are missing. It also offers DequeueAsync<T>(routeKey) and AcknowledgeAsync<T>(routeKey, context).
MessageContext<T>
| Property | Meaning |
|---|---|
Message |
The deserialized payload |
MessageId |
Broker message id. Use it when you report per-message failures |
ReceiptHandle |
Broker handle used to acknowledge the message |
MessageAttributes |
Message attributes as Dictionary<string, string> |
CorrelationId |
Correlation id slot. The SQS provider doesn't populate it |
Consumers
| Contract | Purpose |
|---|---|
IQueueConsumer |
An IQueueManager that is also an IHostedService, with WatchAsync(CancellationToken?) and StopWatch() for polling |
IRouteQueueConsumer |
A consumer for one or more routes on a shared queue |
IQueueConsumerRouter |
Polls a routed queue and dispatches each message by route (WatchAsync / StopWatch) |
AbstractQueueManager |
Abstract base class that implements IQueueManager |
Extension methods in Kanject.Core.Queue.Abstractions.Extensions:
serviceProvider.GetQueueConsumer<T>()resolves a registered consumer. The first instance it resolves is cached per type for the lifetime of the process.serviceProvider.GetRouteQueueConsumer<T>()resolves a route consumer. This one isn't cached, because route consumers are scoped.serviceProvider.UseQueueConsumerRouterWatcher()is defined onServiceProviderand startsWatchAsyncon every hostedIQueueConsumerRouter.
Queue names
QueueNameHelper (in Kanject.Core.Queue.Abstractions.Helpers) holds the naming convention that the SQS provider applies:
| Call | Result |
|---|---|
QueueNameHelper.FormatQueueName("orders") |
orders_queue |
QueueNameHelper.FormatQueueName("orders", "billing") |
billing_orders_queue (lower-cased when a namespace is given) |
QueueNameHelper.FormatQueueName("orders_queue") |
orders_queue. Names that already end in _queue are returned unchanged |
QueueNameHelper.GetDeadletterQueueName("orders_queue") |
orders_queue_dlq |
[QueueName("orders", CreateIfNotExist = true)] marks a consumer class with its queue name, plus an optional namespace as the second argument. QueueNameHelper.GetQueueName, GetQueueAttributeSettings and GetQueueAttribute read that attribute. QueueConstants holds the shared names: QueueRoute, DefaultRouteKey (_), DefaultQueueSuffix (queue) and DeadLetterQueueNamePrefix (dlq).
Scheduling contract
IQueueSchedulerProvider describes delivering a message to a queue later, either once or on a recurring schedule:
| Member | Returns |
|---|---|
CreateScheduleAsync(CreateScheduleRequest, ct) |
CreateScheduleResponse? (ScheduleArn, Name, GroupName) |
UpdateScheduleAsync(UpdateScheduleRequest, ct) |
UpdateScheduleResponse? |
GetScheduleAsync(queueName, scheduleName, groupName, ct) |
GetScheduleResponse?, or null if the schedule doesn't exist |
DeleteScheduleAsync(queueName, scheduleName, groupName, ct) |
DeleteScheduleResponse? (Success) |
CreateScheduleGroupAsync(queueName, groupName, ct) / DeleteScheduleGroupAsync(...) |
Group responses |
The companion attributes live in Kanject.Core.Queue.Abstractions.Attributes:
[SchedulableQueue]marks a message type as schedulable. It has the optional propertiesGroupName,Name,DescriptionandTimeZone(aSystemTimezonefromKanject.Core).[CronSchedule("0 9 * * ? *")]sets a six-field EventBridge cron expression. You can pass it as one string or as separate fields:minutes, hours, dayOfMonth, month, dayOfWeek, year.[RateSchedule(5, RateUnit.Minutes)]sets a fixed-rate expression.RateUnitisMinutes,HoursorDays, and the value must be positive.
The implementation, and the code generator that reads these attributes, ship in the commercial Kanject.Core.Queue.Provider.AwsSqs.Extensions.EventBridge packages.
Trimming and Native AOT
The assembly is marked AOT-compatible. The generic IQueueManager / AbstractQueueManager members serialize TQueueMessage with reflection-based System.Text.Json, so they carry [RequiresUnreferencedCode] and [RequiresDynamicCode]. The trim and AOT analyzers flag those call sites in a trimmed or Native AOT app.
Related packages
| Package | Role | Availability |
|---|---|---|
Kanject.Core.Queue.Provider.AwsSqs |
Amazon SQS implementation of these contracts | nuget.org |
Kanject.Core.Queue.Provider.AwsSqs.Abstractions |
SQS-specific contracts, Lambda handler extensions, partial-batch helpers | nuget.org |
Kanject.Core.Queue.Provider.AwsSqs.Annotations |
Source generator for queue messages and consumers | nuget.org |
Kanject.Core |
Base library this package depends on | nuget.org |
Kanject.Core.Queue.Provider.AwsSqs.Extensions.EventBridge |
EventBridge Scheduler implementation of IQueueSchedulerProvider |
Commercial license (not on nuget.org) |
Kanject.Core.Queue.Provider.AwsSqs.Extensions.EventBridge.Annotations |
Generator for typed schedule helpers | Commercial license (not on nuget.org) |
License
Licensed under the Kanject Code Libraries License Agreement (KCLLA); the full text ships in this package as LICENSE.md. Organizations whose trailing-twelve-month gross revenue and total funding raised are each below US$250,000 may use it at no cost under the Free Tier. At or above either threshold a commercial license is required — contact commercial@kanjectbusiness.com.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. 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 is compatible. 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. |
-
net10.0
- Kanject.Core (>= 3.13.1)
-
net8.0
- Kanject.Core (>= 3.13.1)
-
net9.0
- Kanject.Core (>= 3.13.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Kanject.Core.Queue.Abstractions:
| Package | Downloads |
|---|---|
|
Kanject.Core.Queue.Provider.AwsSqs.Abstractions
Kanject Core Queue AWS Sqs Abstractions |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.8.0 | 42 | 10/2/2026 |
| 3.7.1 | 152 | 9/27/2026 |
| 3.7.0 | 106 | 9/27/2026 |
| 3.6.7 | 117 | 9/26/2026 |
| 3.6.6 | 149 | 9/7/2026 |
| 3.6.5 | 133 | 8/27/2026 |
| 3.6.4 | 144 | 8/22/2026 |
| 3.6.3 | 141 | 8/10/2026 |
| 3.6.2 | 143 | 8/9/2026 |
| 3.6.1 | 147 | 8/5/2026 |
| 3.6.0 | 143 | 8/5/2026 |
| 3.5.0 | 147 | 8/3/2026 |
| 3.4.7 | 156 | 7/30/2026 |
| 3.4.6 | 160 | 7/18/2026 |
| 3.4.5 | 125 | 7/13/2026 |
| 3.4.4 | 141 | 7/11/2026 |
| 3.4.3 | 175 | 7/11/2026 |
| 3.4.2 | 230 | 7/9/2026 |
| 3.4.1 | 162 | 7/9/2026 |