Nuuvify.CommonPack.AzureServiceBus 2.4.0-test.26060602

This is a prerelease version of Nuuvify.CommonPack.AzureServiceBus.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Nuuvify.CommonPack.AzureServiceBus --version 2.4.0-test.26060602
                    
NuGet\Install-Package Nuuvify.CommonPack.AzureServiceBus -Version 2.4.0-test.26060602
                    
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="Nuuvify.CommonPack.AzureServiceBus" Version="2.4.0-test.26060602" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Nuuvify.CommonPack.AzureServiceBus" Version="2.4.0-test.26060602" />
                    
Directory.Packages.props
<PackageReference Include="Nuuvify.CommonPack.AzureServiceBus" />
                    
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 Nuuvify.CommonPack.AzureServiceBus --version 2.4.0-test.26060602
                    
#r "nuget: Nuuvify.CommonPack.AzureServiceBus, 2.4.0-test.26060602"
                    
#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 Nuuvify.CommonPack.AzureServiceBus@2.4.0-test.26060602
                    
#: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=Nuuvify.CommonPack.AzureServiceBus&version=2.4.0-test.26060602&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Nuuvify.CommonPack.AzureServiceBus&version=2.4.0-test.26060602&prerelease
                    
Install as a Cake Tool

Nuuvify.CommonPack.AzureServiceBus

.NET 8.0 Azure Service Bus Thread-Safe NuGet Version License: MIT

Uma biblioteca .NET 8.0 robusta e thread-safe para integração com Azure Service Bus, projetada especificamente para aplicações empresariais, APIs REST e Worker Services.

🚀 Características Principais

  • Thread-Safe: Totalmente thread-safe, ideal para uso como Singleton em APIs REST
  • Alta Performance: Pool de conexões interno e reutilização eficiente de recursos
  • Operações Completas: Suporte a filas, tópicos, operações em lote e agendamento
  • Retry Automático: Retry exponencial com configuração flexível
  • Logging Integrado: Observabilidade completa com Microsoft.Extensions.Logging
  • Configuração Flexível: Suporte a IOptions pattern e configuração programática
  • Dispose Pattern: Implementação correta de IDisposable e IAsyncDisposable
  • Validação Robusta: Validação completa de parâmetros e configurações

📦 Instalação

dotnet add package Nuuvify.CommonPack.AzureServiceBus
dotnet add package Nuuvify.CommonPack.AzureServiceBus.Abstraction

⚙️ Configuração Rápida

1. Configuração no appsettings.json

  • ServiceBus-SuaAplicacao--ConnectionString não deve ser incluido no appsettings.json, é um segredo e por isso estara no Vault
{
  "ServiceBus-SuaAplicacao": {
    "ConnectionString": "Endpoint=sb://seu-namespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=sua-chave",
    "QueueName": "notifications",
    "TopicName": "events",
    "TopicSubscription": "pedidos",
    "OperationTimeoutSeconds": 30,
    "MaxRetryAttempts": 3,
    "RetryDelaySeconds": 5,
    "MaxBatchSize": 100,
    "DefaultMessageTtlMinutes": 60
  }
}

2. Registro no Container de DI

// Program.cs (.NET 8)
using Nuuvify.CommonPack.AzureServiceBus.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Registra como Singleton (recomendado para APIs REST)
builder.Services.AddAzureServiceBus(builder.Configuration);

var app = builder.Build();

3. Uso em Controllers/Services

[ApiController]
[Route("api/[controller]")]
public class NotificationController : ControllerBase
{
    private readonly IServiceBusMessageSender _serviceBus;

    public NotificationController(IServiceBusMessageSender serviceBus)
    {
        _serviceBus = serviceBus;
    }

    [HttpPost("send")]
    public async Task<IActionResult> SendNotification([FromBody] NotificationRequest request)
    {
        await _serviceBus.SendMessageToQueueAsync("notifications", request);
        return Ok(new { Status = "Message sent successfully" });
    }
}

🎯 Casos de Uso Comuns

Envio para Múltiplas Filas (E-commerce)

[ApiController]
public class OrderController : ControllerBase
{
    private readonly IServiceBusMessageSender _serviceBus;

    public OrderController(IServiceBusMessageSender serviceBus)
    {
        _serviceBus = serviceBus;
    }

    [HttpPost("create-order")]
    public async Task<IActionResult> CreateOrder([FromBody] CreateOrderRequest request)
    {
        var order = new Order(request);

        // ✅ Uma única instância Singleton para múltiplas filas
        var tasks = new[]
        {
            // Processamento do pedido
            _serviceBus.SendMessageToQueueAsync("order-processing", order),

            // Email de confirmação
            _serviceBus.SendMessageToQueueAsync("email-notifications",
                new EmailNotification(order.CustomerEmail, "Order Confirmed")),

            // Atualização de estoque
            _serviceBus.SendMessageToQueueAsync("inventory-updates",
                new InventoryUpdate(order.Items)),

            // Análise de dados (usando tópico)
            _serviceBus.SendMessageToTopicAsync("analytics-events",
                new OrderCreatedEvent(order))
        };

        await Task.WhenAll(tasks); // Envio paralelo eficiente

        return Ok(new { OrderId = order.Id });
    }
}

Operações em Lote para Alta Performance

public class BulkNotificationService
{
    private readonly IServiceBusMessageSender _serviceBus;

    public BulkNotificationService(IServiceBusMessageSender serviceBus)
    {
        _serviceBus = serviceBus;
    }

    public async Task SendBulkNotificationsAsync(IEnumerable<User> users)
    {
        var notifications = users.Select(u => new NotificationMessage
        {
            UserId = u.Id,
            Email = u.Email,
            Message = $"Hello {u.Name}!"
        });

        // ✅ Envio em lote - muito mais eficiente
        await _serviceBus.SendBatchMessagesToQueueAsync("notifications", notifications);
    }
}

Mensagens Agendadas

public class ScheduledReminderService
{
    private readonly IServiceBusMessageSender _serviceBus;

    public ScheduledReminderService(IServiceBusMessageSender serviceBus)
    {
        _serviceBus = serviceBus;
    }

    public async Task ScheduleReminder(User user, DateTime reminderTime)
    {
        var reminder = new ReminderMessage
        {
            UserId = user.Id,
            Message = "Don't forget your appointment!",
            ScheduledFor = reminderTime
        };

        // ✅ Agendamento para entrega futura
        var sequenceNumber = await _serviceBus.ScheduleMessageToQueueAsync(
            "reminders",
            reminder,
            reminderTime
        );

        // Salvar sequenceNumber para possível cancelamento
        await SaveReminderSchedule(user.Id, sequenceNumber);
    }
}

🛠️ Configurações Avançadas

Configuração Básica

builder.Services.AddAzureServiceBus(config =>
{
    config.ConnectionString = GetConnectionStringFromKeyVault();
    config.MaxRetryAttempts = 5;
    config.OperationTimeoutSeconds = 60;
    config.EnablePartitioning = true;
});

Configuração Avançada com ServiceBusClientOptions

Para cenários que requerem controle total sobre o cliente Service Bus:

builder.Services.AddAzureServiceBusAdvanced(
    // Configuração básica
    basicConfig =>
    {
        basicConfig.ConnectionString = "Endpoint=sb://mynamespace.servicebus.windows.net/;...";
        basicConfig.OperationTimeoutSeconds = 60;
        basicConfig.MaxRetryAttempts = 5;
        basicConfig.RetryDelaySeconds = 2;
    },
    // Configuração avançada do cliente
    clientConfig =>
    {
        clientConfig.TransportType = ServiceBusTransportType.AmqpTcp; // TCP para melhor performance
        clientConfig.RetryOptions = new ServiceBusRetryOptions
        {
            MaxRetries = 5,
            Delay = TimeSpan.FromSeconds(2),
            MaxDelay = TimeSpan.FromSeconds(30),
            Mode = ServiceBusRetryMode.Exponential
        };
        // Otimização de performance: reutilizar conexões
        clientConfig.ReuseConnections = true; // Padrão: true

        // Para ambientes corporativos com proxy
        clientConfig.WebProxy = new System.Net.WebProxy("http://proxy.company.com:8080");
    });

Configuração com Cliente Pré-configurado

Útil quando você já tem um ServiceBusClient configurado:

// Criar cliente com configurações específicas
var serviceBusClient = new ServiceBusClient(
    "Endpoint=sb://mynamespace.servicebus.windows.net/;...",
    new ServiceBusClientOptions
    {
        TransportType = ServiceBusTransportType.AmqpTcp,
        RetryOptions = new ServiceBusRetryOptions
        {
            MaxRetries = 10,
            Delay = TimeSpan.FromSeconds(1)
        }
    });

builder.Services.AddAzureServiceBusWithClient(serviceBusClient, config =>
{
    config.OperationTimeoutSeconds = 45;
    config.MaxBatchSize = 200;
});

Configuração com Factory Customizada

Para lógica de criação totalmente personalizada:

builder.Services.AddAzureServiceBusWithFactory(
    "Endpoint=sb://mynamespace.servicebus.windows.net/;...",
    (connectionString, options) =>
    {
        // Lógica customizada para criar cliente
        var customOptions = new ServiceBusClientOptions
        {
            TransportType = DetermineTransportType(), // Lógica customizada
            RetryOptions = CreateCustomRetryOptions()  // Baseado em configurações externas
        };
        return new ServiceBusClient(connectionString, customOptions);
    });

Configuração por Operação (Runtime)

Para cenários multi-tenant ou diferentes configurações por contexto:

public class MultiTenantService
{
    private readonly IServiceBusMessageSender _serviceBusMessageSender;

    public MultiTenantService(IServiceBusMessageSender serviceBusMessageSender)
    {
        _serviceBusMessageSender = serviceBusMessageSender;
    }

    public async Task SendMessageForTenant(string tenantId, object message)
    {
        // Cliente customizado para operações de alta prioridade por tenant
        var operationOptions = new ServiceBusOperationOptions
        {
            CustomConnectionString = GetConnectionStringForTenant(tenantId),
            CustomClientOptions = new ServiceBusClientOptions
            {
                TransportType = ServiceBusTransportType.AmqpTcp,
                RetryOptions = new ServiceBusRetryOptions
                {
                    MaxRetries = 10,
                    Delay = TimeSpan.FromMilliseconds(500)
                }
            },
            UseTemporaryClient = true // Cliente será descartado após uso
        };

        var messageOptions = new ServiceBusMessageOptions
        {
            Subject = $"TenantMessage-{tenantId}",
            ApplicationProperties = { ["TenantId"] = tenantId, ["Priority"] = "High" }
        };

        await _serviceBusMessageSender.SendMessageToQueueAsync(
            $"tenant-{tenantId}-queue",
            message,
            messageOptions,
            operationOptions);
    }
}

Exemplo Multi-Ambiente com Diferentes Prioridades

public class PriorityAwareService
{
    private readonly IServiceBusMessageSender _serviceBusMessageSender;

    public PriorityAwareService(IServiceBusMessageSender serviceBusMessageSender)
    {
        _serviceBusMessageSender = serviceBusMessageSender;
    }

    public async Task SendMessage(object message, MessagePriority priority)
    {
        ServiceBusOperationOptions? operationOptions = null;

        if (priority == MessagePriority.High)
        {
            operationOptions = new ServiceBusOperationOptions
            {
                CustomClientOptions = new ServiceBusClientOptions
                {
                    RetryOptions = new ServiceBusRetryOptions
                    {
                        MaxRetries = 10,
                        Delay = TimeSpan.FromMilliseconds(100) // Retry mais rápido para alta prioridade
                    }
                },
                CustomConnectionString = GetHighPriorityConnectionString(),
                UseTemporaryClient = true
            };
        }

        var queueName = priority == MessagePriority.High ? "high-priority-queue" : "normal-queue";

        await _serviceBusMessageSender.SendMessageToQueueAsync(
            queueName,
            message,
            operationOptions: operationOptions);
    }
}

Configuração via Factory (Múltiplas Connection Strings)

builder.Services.AddAzureServiceBus(provider =>
{
    var keyVault = provider.GetRequiredService<IKeyVaultService>();
    return new ServiceBusConfiguration
    {
        ConnectionString = keyVault.GetSecret("ServiceBusConnectionString"),
        MaxRetryAttempts = 5
    };
});

Configurações de Mensagem Personalizadas

var options = new ServiceBusMessageOptions
{
    MessageId = Guid.NewGuid().ToString(),
    CorrelationId = correlationId,
    SessionId = sessionId,
    TimeToLive = TimeSpan.FromHours(2),
    Subject = "Order.Created",
    ContentType = "application/json",
    ApplicationProperties =
    {
        ["TenantId"] = "tenant-123",
        ["Priority"] = "High",
        ["Version"] = "2.0"
    }
};

await _serviceBus.SendMessageToQueueAsync("orders", order, options);

🏗️ Arquitetura e Design

Por que Singleton é Ideal para APIs REST?

  1. Thread-Safety: A implementação é completamente thread-safe
  2. Performance: Reutilização de conexão TCP/TLS (~50-100x mais rápido)
  3. Recursos: Economia de memory, CPU e conexões de rede
  4. Pool Interno: Azure ServiceBusClient já implementa pool de conexões
  5. Múltiplas Filas: Uma instância atende todas as filas eficientemente
// ✅ CORRETO: Singleton para múltiplas filas
services.AddSingleton<IServiceBusMessageSender, ServiceBusMessageSender>();

// ❌ INCORRETO: Desperdiça recursos
services.AddScoped<IServiceBusMessageSender, ServiceBusMessageSender>();
services.AddTransient<IServiceBusMessageSender, ServiceBusMessageSender>(); // Muito problemático

Comparação de Performance

Lifetime Conexões/Request Latência Típica Uso de Memória Recomendado
Singleton 1 (reutilizada) 5-10ms Baixo SIM
Scoped 1 nova por request 500-1000ms Médio ❌ Não
Transient 1 nova por injeção 500-1000ms Alto NUNCA

📋 Interface Completa

A biblioteca oferece métodos para todas as operações principais: Você não precisa implementar isso, basta injetar essa interface em alguma classe no seu projeto "Bus" e consumir esses metodos

public interface IServiceBusMessageSender : IAsyncDisposable
{
    // Envio simples
    Task SendMessageToQueueAsync<T>(string queueName, T message, ServiceBusMessageOptions? options = null, CancellationToken cancellationToken = default);
    Task SendMessageToTopicAsync<T>(string topicName, T message, ServiceBusMessageOptions? options = null, CancellationToken cancellationToken = default);

    // Envio em lote
    Task SendBatchMessagesToQueueAsync<T>(string queueName, IEnumerable<T> messages, ServiceBusMessageOptions? options = null, CancellationToken cancellationToken = default);
    Task SendBatchMessagesToTopicAsync<T>(string topicName, IEnumerable<T> messages, ServiceBusMessageOptions? options = null, CancellationToken cancellationToken = default);

    // Mensagens agendadas
    Task<long> ScheduleMessageToQueueAsync<T>(string queueName, T message, DateTimeOffset scheduledEnqueueTime, ServiceBusMessageOptions? options = null, CancellationToken cancellationToken = default);
    Task<long> ScheduleMessageToTopicAsync<T>(string topicName, T message, DateTimeOffset scheduledEnqueueTime, ServiceBusMessageOptions? options = null, CancellationToken cancellationToken = default);

    // Cancelamento de agendamento
    Task CancelScheduledMessageInQueueAsync(string queueName, long sequenceNumber, CancellationToken cancellationToken = default);
    Task CancelScheduledMessageInTopicAsync(string topicName, long sequenceNumber, CancellationToken cancellationToken = default);
}

🔧 Troubleshooting

Problemas Comuns

  1. Connection String Inválida

    Erro: ArgumentException - Invalid connection string
    Solução: Verificar format no portal Azure
    
  2. Timeout em Operações

    Erro: ServiceBusException - Operation timed out
    Solução: Aumentar OperationTimeoutSeconds na configuração
    
  3. Fila/Tópico Não Existe

    Erro: ServiceBusException - Entity not found
    Solução: Criar a entidade no portal Azure ou verificar nome
    

Logs Úteis

A biblioteca produz logs detalhados:

// Ativar logs no appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Nuuvify.CommonPack.AzureServiceBus": "Information"
    }
  }
}

🧪 Testes

Cobertura de Testes

A biblioteca possui cobertura de testes abrangente com mais de 300 testes unitários e de integração:

  • 49.6% de cobertura de linha para ServiceBusMessageReceiver
  • 70% de cobertura para ServiceBusMessageSender
  • 96.9% de cobertura para ServiceBusConfigurationManager
  • 44 testes específicos para ServiceBusMessageReceiver e classes parciais

Estrutura de Testes

Os testes estão organizados por funcionalidade:

Nuuvify.CommonPack.AzureServiceBus.xTest/
├── Configuration/           # Testes de configuração
├── Services/               # Testes de serviços
│   ├── ServiceBusMessageSender*Tests.cs
│   ├── ServiceBusMessageReceiver*Tests.cs
│   └── ServiceBusConfiguration*Tests.cs
└── Fixtures/               # Fixtures e helpers de teste

Exemplo de Teste Unitário (Sender)

[Fact]
public async Task SendMessage_ShouldSucceed_WhenValidConfiguration()
{
    // Arrange
    var config = new ServiceBusConfiguration
    {
        ConnectionString = TestConnectionString,
        MaxRetryAttempts = 1
    };

    var sender = new ServiceBusMessageSender(
        Options.Create(config),
        new NullLogger<ServiceBusMessageSender>()
    );

    // Act & Assert
    await sender.SendMessageToQueueAsync("test-queue", new { Message = "Test" });

    // Cleanup
    await sender.DisposeAsync();
}

Exemplo de Teste Unitário (Receiver)

[Fact]
public async Task Constructor_WithValidParameters_ShouldCreateInstance()
{
    // Arrange
    var loggerMock = new Mock<ILogger<TestServiceBusMessageReceiver>>();
    var configMock = new Mock<IConfigurationCustom>();
    var requestConfig = new RequestConfiguration { CorrelationId = Guid.NewGuid().ToString() };

    // Act
    await using var receiver = new TestServiceBusMessageReceiver(
        loggerMock.Object,
        configMock.Object,
        requestConfig);

    // Assert
    Assert.NotNull(receiver);
    Assert.False(receiver.IsProcessing);
}

Testes de Thread Safety

[Fact]
public async Task IsProcessing_ThreadSafety_ShouldHandleConcurrentAccess()
{
    // Arrange
    await using var receiver = new TestServiceBusMessageReceiver(logger, config, requestConfig);
    var tasks = new List<Task<bool>>();

    // Act - Access IsProcessing from multiple threads
    for (int i = 0; i < 10; i++)
    {
        tasks.Add(Task.Run(() => receiver.IsProcessing));
    }

    var results = await Task.WhenAll(tasks);

    // Assert - All should return same value
    Assert.All(results, result => Assert.False(result));
}

Executando os Testes

# Todos os testes
dotnet test

# Apenas testes do AzureServiceBus
dotnet test --filter "FullyQualifiedName~AzureServiceBus"

# Com cobertura de código
dotnet test --collect:"XPlat Code Coverage"

# Gerar relatório de cobertura
reportgenerator -reports:"**/*.cobertura.xml" -targetdir:"CoverageReport"

Ferramentas de Teste Utilizadas

  • xUnit - Framework de testes principal
  • Moq - Framework de mock para interfaces e classes
  • Shouldly - Biblioteca de assertions mais expressivas
  • Bogus - Geração de dados fake para testes
  • ReportGenerator - Geração de relatórios de cobertura
  • Custom TestHelpers - Classes de apoio específicas para ServiceBus

⚡ Otimização de Performance: ReuseConnections

O que é ReuseConnections?

A propriedade ReuseConnections na ServiceBusClientConfiguration controla se os clientes criados temporariamente pelas ServiceBusOperationOptions devem ser reutilizados ou criados a cada operação.

Como Funciona

// Configuração com cache habilitado (padrão)
services.AddAzureServiceBusWithClientConfiguration(configuration, clientConfig =>
{
    clientConfig.ReuseConnections = true; // Padrão
});

// Exemplo de uso que beneficia do cache
var options = new ServiceBusOperationOptions
{
    CustomConnectionString = "Endpoint=sb://específico.servicebus.windows.net/;...",
    CustomClientOptions = new ServiceBusClientOptions
    {
        TransportType = ServiceBusTransportType.AmqpWebSockets
    }
};

// Múltiplas operações com as mesmas configurações
// reutilizarão o mesmo cliente (economiza recursos)
for (int i = 0; i < 100; i++)
{
    await sender.SendMessageToQueueAsync("queue", message, options);
}

Benefícios

  • Performance: Evita overhead de criação/destruição de conexões TCP
  • Recursos: Reduz uso de memória e handles de rede
  • Latência: Operações subsequentes são mais rápidas
  • Throughput: Maior taxa de transferência para operações em lote

Quando Usar ReuseConnections = false

clientConfig.ReuseConnections = false; // Para debug ou casos específicos
  • Debugging: Para isolar problemas de conexão
  • Testes: Garantir estado limpo entre testes
  • Configurações únicas: Cada operação precisa de cliente específico

Chave do Cache

O cache usa uma chave baseada em:

  • Connection String
  • TransportType
  • Configurações de Retry (MaxRetries, Mode)

Operações com configurações idênticas compartilham o mesmo cliente.

📊 Dependências

  • .NET 8.0 - Framework principal
  • Microsoft.Extensions.Logging - Logging concreto (implementação)
  • Microsoft.Extensions.Options.ConfigurationExtensions - Extensões de configuração
  • Nuuvify.CommonPack.AzureServiceBus.Abstraction - Interfaces e abstrações

Dependências Herdadas (via Abstraction)

  • Azure.Messaging.ServiceBus - Cliente oficial do Azure Service Bus
  • Microsoft.Extensions.Logging.Abstractions - Abstrações de logging
  • Microsoft.Extensions.Configuration.Abstractions - Abstrações de configuração
  • Microsoft.Extensions.Options - Sistema de opções do .NET
  • Microsoft.Extensions.DependencyInjection.Abstractions - Abstrações de DI

Organização do Código

O projeto utiliza uma arquitetura modular com GlobalUsings.cs centralizando todas as declarações using:

// GlobalUsings.cs - Centraliza using statements
global using Azure.Messaging.ServiceBus;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Options;
// ... outros usings globais

Qualidade do Código

  • Nullable Reference Types: Habilitado a nível de projeto (não por arquivo)
  • SonarQube Compliant: Supressões apropriadas para falsos positivos
  • EditorConfig: Padronização de estilo seguindo .editorconfig do projeto
  • Code Coverage: Monitoramento contínuo com metas de cobertura
  • Thread-Safe: Design thread-safe para uso em aplicações concorrentes

📄 Licença

Este projeto está licenciado sob a Licença MIT.

🤝 Contribuição

Contribuições são bem-vindas! Por favor:

  1. Fork o projeto
  2. Crie uma feature branch (git checkout -b feature/nova-funcionalidade)
  3. Commit suas mudanças (git commit -am 'Adiciona nova funcionalidade')
  4. Push para a branch (git push origin feature/nova-funcionalidade)
  5. Abra um Pull Request

📞 Suporte

Para dúvidas e suporte técnico:

📈 Versionamento

Este projeto segue o Semantic Versioning:

  • MAJOR: Mudanças incompatíveis na API
  • MINOR: Novas funcionalidades mantendo compatibilidade
  • PATCH: Correções de bugs mantendo compatibilidade

Consulte o CHANGELOG.md para ver todas as mudanças detalhadas.

🏢 Sobre a Nuuvify

A Nuuvify é uma empresa especializada em soluções tecnológicas para transformação digital, oferecendo bibliotecas e ferramentas robustas para acelerar o desenvolvimento de aplicações empresariais.

Outros Pacotes da CommonPack


Desenvolvido com ❤️ pela equipe Nuuvify.

Product 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 was computed.  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.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.5.0-test.26060608 0 6/6/2026
2.5.0-test.26060606 0 6/6/2026
2.4.0-test.26060602 0 6/6/2026
2.4.0-test.26041707 0 4/17/2026
2.3.0-test.26033106 0 3/31/2026
2.2.0-test.25102904 0 10/29/2025
2.2.0-test.25102902 0 10/29/2025
2.2.0-test.25102802 0 10/29/2025
2.1.0-test.25101302 137 10/13/2025
2.1.0-test.25101102 1 10/12/2025

# Changelog - Nuuvify.CommonPack.AzureServiceBus

Todas as mudanças notáveis deste pacote serão documentadas neste arquivo.

O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-br/1.0.0/),
e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/spec/v2.0.0.html).

## [Não Lançado]

### Adicionado
- Suporte a `ReceiveMode` no `ServiceBusMessageReceiver`, com exposição do modo configurado para customizações em classes derivadas.

### Alterado
- Fluxo de processamento ajustado para evitar `CompleteMessageAsync` quando o receiver estiver em `ReceiveAndDelete`.
- Tratamento de exceções e de falhas de regra de negócio ajustado para comportamento compatível com `ReceiveAndDelete`, sem tentar operações de settlement não permitidas.

### Corrigido
- Evitadas tentativas de `DeadLetter`/`Abandon` em cenários `ReceiveAndDelete`, reduzindo falhas operacionais durante o consumo.

### Removido

### Segurança

## [Sem versão registrada] - 2025-10-13

### Alterado
- Removido `#nullable enable` individualizado de todos os arquivos fonte; configuração centralizada no projeto.
- Dependências redundantes removidas (herdadas via projeto de abstração): `Azure.Messaging.ServiceBus`, `Microsoft.Extensions.Options`, `Microsoft.Extensions.Logging.Abstractions`, `Microsoft.Extensions.Configuration.Abstractions`, `Microsoft.Extensions.DependencyInjection.Abstractions`.
- `using` statements centralizados em `GlobalUsings.cs`.

### Adicionado
- Tags de `PackageTags` no `.csproj` para melhor descoberta no NuGet.

## [Sem versão registrada] - 2025-10-08

### Adicionado
- Release inicial do `Nuuvify.CommonPack.AzureServiceBus`.
- Interface `IServiceBusMessageSender` com operações para filas e tópicos: envio simples, envio em lote, agendamento e cancelamento de mensagens agendadas.
- Classe de configuração `ServiceBusConfiguration` via `IOptions` pattern.
- Classe de opções `ServiceBusMessageOptions` para personalização de mensagens (id, correlação, sessão, TTL, agendamento).
- Extensões de DI: `AddAzureServiceBus` com sobrecarga por `IConfiguration`, `Action<ServiceBusConfiguration>` e factory com `IServiceProvider`.
- Suporte a `CancellationToken` em todas as operações.
- Implementação de `IDisposable` e `IAsyncDisposable`.