Uma biblioteca .NET leve e resiliente para criar listeners (Hosted Services) para o Oracle Advanced Queuing (AQ). Integra-se com injeção de dependência para descobrir e gerenciar seus processadores de mensagens de forma automática, com lógica de reconexão e mapeamento de UDTs embutidos.
$ dotnet add package SquareLabs.OracleAQ.ExtensionsUma biblioteca .NET leve e resiliente para criar listeners (Hosted Services) para o Oracle Advanced Queuing (AQ). Integra-se com injeção de dependência para descobrir e gerenciar seus processadores de mensagens de forma automática, com lógica de reconexão e mapeamento de UDTs embutidos.
Interagir com o Oracle Advanced Queuing em uma aplicação .NET moderna pode ser verboso e complexo, especialmente ao tentar criar serviços de background robustos e resilientes. Esta biblioteca abstrai toda a complexidade de gerenciamento de conexões, transações de fila, mapeamento de objetos e descoberta de serviços, permitindo que você foque no que realmente importa: a sua lógica de negócio.
IOracleAQListener<T> e a biblioteca irá descobrir, registrar e executar seu listener automaticamente.DbContext do EF Core ou um IHubContext do SignalR) em seus listeners.A instalação é feita através do gerenciador de pacotes NuGet:
dotnet add package SquareLabs.OracleAQ.Extensions
Primeiro, você precisa criar uma factory para o seu tipo UDT do Oracle. Esta classe implementa as interfaces necessárias do driver Oracle:
using Oracle.ManagedDataAccess.Client;
using Oracle.ManagedDataAccess.Types;
public class PedidoUdtFactory : IOracleCustomType, IOracleCustomTypeFactory
{
// Implementação da factory para mapear o UDT Oracle para a classe C#
[OracleObjectMapping("ID")]
public decimal? Id { get; set; }
[OracleObjectMapping("DESCRICAO")]
public string? Descricao { get; set; }
[OracleObjectMapping("VALOR")]
public decimal? Valor { get; set; }
public IOracleCustomType CreateObject()
{
return new PedidoUdtFactory();
}
public void FromCustomObject(OracleConnection con, object udt)
{
if (udt is PedidoDto pedido)
{
Id = pedido.Id;
Descricao = pedido.Descricao;
Valor = pedido.Valor;
}
}
public void ToCustomObject(OracleConnection con, object udt)
{
// Conversão do UDT Oracle para o objeto customizado
}
}
Crie uma classe C# que representa sua mensagem, usando os atributos de mapeamento:
using SquareLabs.OracleAQ.Extensions.Domain.Attributes;
public class PedidoDto
{
[OracleUdtProperty("ID")]
public decimal? Id { get; set; }
[OracleUdtProperty("DESCRICAO")]
public string? Descricao { get; set; }
[OracleUdtProperty("VALOR")]
public decimal? Valor { get; set; }
}
Implemente a interface IOracleAQListener<T> para processar as mensagens:
using Microsoft.Extensions.Logging;
using SquareLabs.OracleAQ.Extensions.Domain.Interfaces;
public class PedidoListener : IOracleAQListener<PedidoDto>
{
private readonly ILogger<PedidoListener> _logger;
private readonly IPedidoService _pedidoService;
public PedidoListener(ILogger<PedidoListener> logger, IPedidoService pedidoService)
{
_logger = logger;
_pedidoService = pedidoService;
}
public string QueueName => "PEDIDOS_QUEUE";
public async Task ProcessMessageAsync(PedidoDto message, CancellationToken cancellationToken)
{
_logger.LogInformation("Processando pedido {PedidoId}", message.Id);
try
{
await _pedidoService.ProcessarPedidoAsync(message, cancellationToken);
_logger.LogInformation("Pedido {PedidoId} processado com sucesso", message.Id);
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao processar pedido {PedidoId}", message.Id);
throw; // Re-throw para que a mensagem seja colocada de volta na fila
}
}
}
Configure a biblioteca no seu Program.cs:
using SquareLabs.OracleAQ.Extensions.Infrastructure;
var builder = WebApplication.CreateBuilder(args);
// Registrar seus serviços de negócio
builder.Services.AddScoped<IPedidoService, PedidoService>();
// Registrar os listeners Oracle AQ
builder.Services.AddOracleAQListeners(options =>
{
options.ConnectionStringName = "OracleConnection";
// Configurar o mapeamento UDT
options.RegisterQueueUdt("PEDIDOS_QUEUE", "PEDIDO_UDT");
// NOVO: Para Oracle 10g, habilite o modo de compatibilidade
// options.UseOracle10gCompatibilityMode = true;
});
var app = builder.Build();
// Configure o pipeline HTTP...
app.Run();
E no seu appsettings.json:
{
"ConnectionStrings": {
"OracleConnection": "Data Source=localhost:1521/XE;User Id=seu_usuario;Password=sua_senha;"
}
}
Nota: Embora a biblioteca funcione com versões legadas como Oracle 11g e 10g, recomendamos usar Oracle 19c ou superior para melhor suporte e recursos de segurança.
Se você estiver usando Oracle 10g e encontrar o erro:
ORA-06550: linha 1, coluna 13:
PLS-00306: número incorreto de tipos de argumentos na chamada para 'GET_TYPE_SHAPE'
Habilite o modo de compatibilidade Oracle 10g:
services.AddOracleAQListeners(options =>
{
options.ConnectionStringName = "OracleConnection";
options.RegisterQueueUdt("SUA_FILA", "SEU_TIPO_UDT");
// Habilita modo de compatibilidade com Oracle 10g
options.UseOracle10gCompatibilityMode = true;
});
Este modo implementa estratégias de fallback específicas para contornar limitações do Oracle 10g com funções mais recentes do driver Oracle.
Contribuições são muito bem-vindas! Para contribuir com o projeto:
git checkout -b feature/minha-nova-feature)git commit -am 'feat: adiciona nova feature')git push origin feature/minha-nova-feature)Este projeto usa Commits Semânticos. Use os seguintes tipos:
feat: Nova funcionalidadefix: Correção de bugdocs: Alterações na documentaçãostyle: Formatação, ponto e vírgula ausente, etcrefactor: Refatoração de códigotest: Adição ou correção de testeschore: Manutenção, build, dependênciasExemplo: feat: adiciona suporte para múltiplas connection strings
Autor: Rômulo Eduardo (@romuloedu)
Licença: MIT License
Se esta biblioteca foi útil para você, considere dar uma estrela ⭐ no repositório do GitHub! Isso ajuda outros desenvolvedores a descobrirem o projeto e motiva a continuidade do desenvolvimento.