Codebelt

Savvyio.Extensions.DependencyInjection.SimpleQueueService

Register AWS-backed Savvy I/O channels in Microsoft DI, including marker-specific queue and bus resolution.

.NET 10.0 / .NET 9.0 MIT v5.0.8 9,167 downloads

Overview

Savvyio.Extensions.DependencyInjection.SimpleQueueService wires the AWS transport from Savvyio.Extensions.SimpleQueueService into IServiceCollection for Savvy I/O command queues and integration event buses. It adds registration methods for the default queue and bus types plus marker-specific variants, so consumers resolve AWS-backed channels through Savvy I/O abstractions instead of concrete transport classes.

The package does not provide a marshaller or new transport behavior on its own. It composes the existing SNS and SQS implementations with the dependency injection helpers from Savvyio.Extensions.DependencyInjection, including singleton defaults and configured options registration.

Key APIs

AddAmazonCommandQueue registers the non-marker AmazonCommandQueue as a message queue for ICommand and stores the supplied AmazonCommandQueueOptions in the container. The implementation defaults to ServiceLifetime.Singleton, and the tests show the registration resolves through IPointToPointChannel<ICommand>, ISender<ICommand>, and IReceiver<ICommand>.

AddAmazonCommandQueue<TMarker> registers the marker-aware AmazonCommandQueue<TMarker> and forwards it to the marker-specific command channel interfaces. Use this overload when the container needs a distinct queue identity such as IPointToPointChannel<ICommand, TMarker>.

AddAmazonEventBus registers the non-marker AmazonEventBus as the publish-subscribe channel for IIntegrationEvent and stores the supplied AmazonEventBusOptions. The tests verify that the same registration is available through IPublishSubscribeChannel<IIntegrationEvent>, IPublisher<IIntegrationEvent>, and ISubscriber<IIntegrationEvent>.

AddAmazonEventBus<TMarker> registers the marker-aware AmazonEventBus<TMarker> for IPublishSubscribeChannel<IIntegrationEvent, TMarker> and the related publisher and subscriber interfaces. It mirrors the non-generic overload while keeping the registration scoped by marker type.

AmazonCommandQueue<TMarker> derives from Savvyio.Extensions.SimpleQueueService.Commands.AmazonCommandQueue and implements IPointToPointChannel<ICommand, TMarker>. Its constructor keeps the lower-level IMarshaller and AmazonCommandQueueOptions<TMarker> contract while making the queue visible to the marker-based DI surface.

AmazonCommandQueueOptions<TMarker> inherits Savvyio.Extensions.SimpleQueueService.Commands.AmazonCommandQueueOptions and adds IDependencyInjectionMarker<TMarker>. The wrapper does not introduce new properties, so queue setup still comes from the inherited AWS options such as Credentials, Endpoint, SourceQueue, and ReceiveContext.

AmazonEventBus<TMarker> derives from Savvyio.Extensions.SimpleQueueService.EventDriven.AmazonEventBus and implements IPublishSubscribeChannel<IIntegrationEvent, TMarker>. It is the marker-aware counterpart that lets DI resolve an AWS event bus through the marker-specific publish-subscribe interfaces.

AmazonEventBusOptions<TMarker> inherits Savvyio.Extensions.SimpleQueueService.EventDriven.AmazonEventBusOptions and adds IDependencyInjectionMarker<TMarker>. Like the queue options wrapper, it keeps the lower-level AWS configuration model intact while binding the options to a marker type.

Basic usage

using System;
using System.IO;
using Amazon;
using Amazon.Runtime;
using Codebelt.Extensions.Xunit;
using Microsoft.Extensions.DependencyInjection;
using Savvyio;
using Savvyio.Commands;
using Savvyio.Extensions.DependencyInjection;
using Savvyio.Extensions.DependencyInjection.Messaging;
using Savvyio.Extensions.DependencyInjection.SimpleQueueService;
using Savvyio.Extensions.DependencyInjection.SimpleQueueService.Commands;
using Xunit;

namespace MyProject.Tests;

public class AmazonCommandQueueRegistrationTests : Test
{
    public AmazonCommandQueueRegistrationTests(ITestOutputHelper output) : base(output) { }

    [Fact]
    public void AddAmazonCommandQueue_WithMarker_RegistersTypedChannelAndOptions()
    {
        var services = new ServiceCollection();
        services.AddMarshaller<NoOpMarshaller>(_ => new NoOpMarshaller());
        services.AddAmazonCommandQueue<OrdersQueueMarker>(options =>
        {
            options.Credentials = new AnonymousAWSCredentials();
            options.Endpoint = RegionEndpoint.EUWest1;
            options.SourceQueue = new Uri("urn:queue:orders");
        });

        using var provider = services.BuildServiceProvider();
        var channel = provider.GetRequiredService<IPointToPointChannel<ICommand, OrdersQueueMarker>>();
        var configure = provider.GetRequiredService<Action<AmazonCommandQueueOptions<OrdersQueueMarker>>>();
        var configured = new AmazonCommandQueueOptions<OrdersQueueMarker>();
        configure(configured);

        TestOutput.WriteLine($"Resolved channel: {channel.GetType().Name}");
        TestOutput.WriteLine($"Configured queue: {configured.SourceQueue}");
        Assert.IsType<AmazonCommandQueue<OrdersQueueMarker>>(channel);
        Assert.Equal("urn:queue:orders", configured.SourceQueue.OriginalString);
    }

    private readonly struct OrdersQueueMarker;

    private sealed class NoOpMarshaller : IMarshaller
    {
        public Stream Serialize<TValue>(TValue value) => Stream.Null;
        public Stream Serialize(object value, Type inputType) => Stream.Null;
        public TValue Deserialize<TValue>(Stream data) => throw new NotSupportedException();
        public object Deserialize(Stream data, Type returnType) => throw new NotSupportedException();
    }
}

Use this pattern when you want a marker-specific AWS command queue registered once and resolved through Savvy I/O dependency injection abstractions. It matters because the package binds the AWS queue settings into the container and exposes the transport through the marker-specific command channel contract.

Installation

dotnet add package Savvyio.Extensions.DependencyInjection.SimpleQueueService

Usage guidance

Use this package when your application already models commands or integration events with Savvy I/O abstractions and you want IServiceCollection to expose AWS-backed channels, especially when marker types separate multiple registrations in the same container. Register an IMarshaller before resolving these services, and configure Credentials, Endpoint, and SourceQueue because the underlying AWS options validate those values. If you do not need Microsoft DI registration or Savvy I/O channel abstractions, use Savvyio.Extensions.SimpleQueueService or the plain AWS SDK directly.

Family packages