Implementações de Integradores
O framework de integrações permite criar soluções robustas e escaláveis para conectar sistemas de forma consistente. Cada integrador encapsula a lógica de coleta, transformação e envio de dados, garantindo que o processo seja confiável, monitorado e fácil de manter.
Entre os principais benefícios para o desenvolvedor:
- Isolamento de operações: cada execução ocorre de forma independente, evitando efeitos colaterais entre execuções.
- Paralelismo e concorrência automática: o framework gerencia múltiplas execuções simultâneas, respeitando limites de concorrência configuráveis.
- Integração completa com o .NET DI: você tem acesso a todos os serviços registrados, como clientes HTTP, repositórios, loggers, etc., sem precisar instanciar manualmente.
- Execução periódica ou baseada em eventos: escolha entre polling para consultas periódicas ou processamento reativo a mensagens.
- Métricas e tratamento de erros prontos: logging, contadores e monitoramento integrados, sem configuração adicional.
A estrutura do integrador ajuda a manter o código limpo e organizado, separando responsabilidades de forma clara: Query para buscar dados, Parse para transformá-los e Send para processar ou enviar. Isso torna o desenvolvimento mais seguro, testável e performático.
Integrações por Pooling
Implementação para integrações baseadas em polling, executadas periodicamente.
Exemplo de Integrador
Abaixo, um integrador baseado em polling que consulta uma API externa, transforma os dados e envia para outro sistema:
public class B1PoolingIntegrator(ICustomerService customerService) : PoolingIntegrator<CustomerDto, CustomerProcessed>
{
protected override async Task<CustomerDto> Query()
{
// Consulta a API externa e retorna os dados
var customers = await customerService.getCustomers();
return customers.FirstOrDefault();
}
protected override async Task<CustomerProcessed> Parse(CustomerDto data)
{
// Transforma os dados brutos no formato necessário
return new CustomerProcessed
{
Id = data.Id,
Name = data.FullName.ToUpper(),
Email = data.Email.ToLower()
};
}
protected override async Task<CustomerProcessed> Send(CustomerProcessed parsedData)
{
// Envia os dados processados para outro sistema
await ExternalSystemClient.SendCustomerAsync(parsedData);
return parsedData;
}
}
Assinatura
public abstract class PoolingIntegrator<TInput, TOutput> : BaseIntegrator<TInput, TOutput>
Método de Execução
public Task<IntegrationResult<TOutput>> Execute()
Executa o integrador seguindo o fluxo: Query → Parse → Send.
Métodos Abstratos Obrigatórios
| Método | Descrição |
|---|---|
Query() | Obter os dados que serão processados (TInput). Ex.: consultar API, banco de dados ou arquivos. |
Parse(TInput data) | Transformar os dados de entrada no formato necessário (TOutput). |
Send(TOutput parsedData) | Enviar, processar ou persistir os dados transformados. |
Integrações por messageria
Implementação para integrações baseadas em mensagens, disparadas por eventos ou filas.
Exemplo de Integrador
Abaixo, um integrador baseado em polling que consulta uma API externa, transforma os dados e envia para outro sistema:
public class B1PoolingIntegrator(ICustomerService customerService) : MessageProcessorIntegrator<MessageDto, CustomerDto, CustomerProcessed>
{
protected override async Task<CustomerDto> Query(MessageDto message)
{
// Consulta a API externa e retorna os dados
var customer = await customerService.getCustomer(message.customer);
return customer;
}
protected override async Task<CustomerProcessed> Parse(CustomerDto data)
{
// Transforma os dados brutos no formato necessário
return new CustomerProcessed
{
Id = data.Id,
Name = data.FullName.ToUpper(),
Email = data.Email.ToLower()
};
}
protected override async Task<CustomerProcessed> Send(CustomerProcessed parsedData)
{
// Envia os dados processados para outro sistema
await ExternalSystemClient.SendCustomerAsync(parsedData);
return parsedData;
}
}
Assinatura
public abstract class MessageProcessorIntegrator<TMessage, TInput, TOutput> : BaseIntegrator<TInput, TOutput>
Método de Execução
public Task<IntegrationResult<TOutput>> Execute(TMessage message)
Executa a integração baseada em uma mensagem específica, seguindo o mesmo fluxo: Query → Parse → Send.
Métodos Abstratos Obrigatórios
| Método | Descrição |
|---|---|
Query(TMessage message) | Obter os dados usando informações da mensagem (TInput). |
Parse(TInput data) | Transformar os dados de entrada no formato necessário (TOutput). |
Send(TOutput parsedData) | Enviar, processar ou persistir os dados transformados. |
Comparação das Implementações
| Característica | PoolingIntegrator | MessageProcessorIntegrator |
|---|---|---|
| Modelo de Execução | Polling / Consulta periódica | Baseado em mensagens / eventos |
| Método Execute | Execute() | Execute(TMessage message) |
| Query | Sem parâmetros | Recebe message como parâmetro |
| Uso Típico | Sincronização periódica, jobs agendados | Processamento de eventos, filas de mensagens |
Funcionalidades Herdadas do BaseIntegrator
- ✅ Métricas automáticas (tempo, contadores, throughput)
- ✅ Tratamento centralizado de erros
- ✅ Hooks de execução:
PreExecution,PostExecution,OnError - ✅ Validações automáticas:
ValidateQuery,ValidateParse - ✅ Retorno padronizado com
IntegrationResult<TOutput>
Boas Práticas
- Query e Parse: mantenha simples e focado, evitando lógica complexa dentro de
Query. - Send: trate apenas persistência ou envio; não faça transformações aqui.
- Escolha da implementação:
- Polling → quando precisa executar periodicamente
- MessageProcessor → quando cada execução é disparada por evento/mensagem
- Métricas e monitoramento: não é necessário implementar manualmente; já é automático.
Com este padrão, o fluxo Query → Parse → Send fica claro e consistente, independente do tipo de integração.