<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Luciano Azevedo</title>
    <description>The latest articles on Forem by Luciano Azevedo (@oluciaano).</description>
    <link>https://forem.com/oluciaano</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2578506%2F87fc6ae6-24ea-4381-9b8a-c4cc17457c5f.jpg</url>
      <title>Forem: Luciano Azevedo</title>
      <link>https://forem.com/oluciaano</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/oluciaano"/>
    <language>en</language>
    <item>
      <title>🏗️ Aplicando Adapter e Decorator Patterns com Injeção de Dependência no C#</title>
      <dc:creator>Luciano Azevedo</dc:creator>
      <pubDate>Sun, 02 Feb 2025 22:00:25 +0000</pubDate>
      <link>https://forem.com/oluciaano/aplicando-adapter-e-decorator-patterns-com-injecao-de-dependencia-no-c-2cb4</link>
      <guid>https://forem.com/oluciaano/aplicando-adapter-e-decorator-patterns-com-injecao-de-dependencia-no-c-2cb4</guid>
      <description>&lt;p&gt;Ao desenvolver software, muitas vezes precisamos integrar sistemas legados e adicionar funcionalidades sem modificar diretamente o código existente. Para isso, podemos usar padrões de design como Adapter e Decorator, que nos ajudam a estruturar o código de forma modular e reutilizável.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos explorar como usar esses padrões no C# com injeção de dependência (DI) e a biblioteca Scrutor para simplificar o registro dos decorators.&lt;/p&gt;

&lt;p&gt;🎯 Cenário do Problema&lt;/p&gt;

&lt;p&gt;Imagine que temos um serviço legado que processa pagamentos, mas ele não segue a interface moderna que queremos usar em nosso sistema. Além disso, queremos adicionar logs ao processamento de pagamentos sem modificar diretamente o serviço existente.&lt;/p&gt;

&lt;p&gt;Vamos resolver isso combinando Adapter e Decorator!&lt;/p&gt;

&lt;p&gt;📌 Passo 1: Definindo a Interface Padrão&lt;/p&gt;

&lt;p&gt;Criamos a interface IPaymentProcessor para definir um contrato padrão para processadores de pagamento:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface IPaymentProcessor
{
    void ProcessPayment(decimal amount);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa interface será usada tanto pelo Adapter quanto pelo Decorator.&lt;/p&gt;

&lt;p&gt;📌 Passo 2: Criando o Serviço Legado&lt;/p&gt;

&lt;p&gt;Nosso serviço legado (LegacyPaymentService) não segue a interface moderna. Ele espera um string em vez de um decimal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public sealed class LegacyPaymentService
{
    public void MakePayment(string amount)
    {
        Console.WriteLine($"Processing payment of {amount} via legacy system.");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para integrá-lo ao sistema moderno, usaremos o Adapter Pattern.&lt;/p&gt;

&lt;p&gt;📌 Passo 3: Criando o Adapter&lt;/p&gt;

&lt;p&gt;O Adapter faz a conversão entre IPaymentProcessor e LegacyPaymentService:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public sealed class PaymentAdapter : IPaymentProcessor
{
    private readonly LegacyPaymentService _legacyPaymentService;

    public PaymentAdapter(LegacyPaymentService legacyPaymentService)
    {
        _legacyPaymentService = legacyPaymentService;
    }

    public void ProcessPayment(decimal amount)
    {
        string amountString = amount.ToString("F2");
        _legacyPaymentService.MakePayment(amountString);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora podemos usar PaymentAdapter em qualquer lugar que espera IPaymentProcessor.&lt;/p&gt;

&lt;p&gt;📌 Passo 4: Criando o Decorator para Logging&lt;/p&gt;

&lt;p&gt;Agora adicionamos um Decorator (LoggingDecorator) para registrar logs sempre que um pagamento for processado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.Extensions.Logging;

public class LoggingDecorator : IPaymentProcessor
{
    private readonly IPaymentProcessor _innerProcessor;
    private readonly ILogger&amp;lt;LoggingDecorator&amp;gt; _logger;

    public LoggingDecorator(IPaymentProcessor innerProcessor, ILogger&amp;lt;LoggingDecorator&amp;gt; logger)
    {
        _innerProcessor = innerProcessor;
        _logger = logger;
    }

    public void ProcessPayment(decimal amount)
    {
        _logger.LogInformation($"Iniciando processamento do pagamento de {amount:C}");
        _innerProcessor.ProcessPayment(amount);
        _logger.LogInformation($"Pagamento de {amount:C} processado com sucesso.");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse Decorator adiciona logs antes e depois da chamada real ao PaymentProcessor, sem modificar sua implementação.&lt;/p&gt;

&lt;p&gt;📌 Passo 5: Criando o Worker Service&lt;/p&gt;

&lt;p&gt;Para simular um sistema em execução contínua, criamos um Worker Service que chama IPaymentProcessor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;

public class PaymentWorker : BackgroundService
{
    private readonly ILogger&amp;lt;PaymentWorker&amp;gt; _logger;
    private readonly IPaymentProcessor _paymentProcessor;

    public PaymentWorker(ILogger&amp;lt;PaymentWorker&amp;gt; logger, IPaymentProcessor paymentProcessor)
    {
        _logger = logger;
        _paymentProcessor = paymentProcessor;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Iniciando ciclo do Worker...");

            _paymentProcessor.ProcessPayment(100.50m); // Simulando pagamento

            await Task.Delay(5000, stoppingToken); // Executa a cada 5 segundos
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📌 Passo 6: Configurando a Injeção de Dependência (DI) com Scrutor&lt;/p&gt;

&lt;p&gt;Podemos usar a biblioteca Scrutor para simplificar o registro do Decorator.&lt;br&gt;
Primeiro, instalamos a dependência via NuGet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package Scrutor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, configuramos os serviços no Program.cs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Scrutor;

class Program
{
    static void Main(string[] args)
    {
        var host = Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =&amp;gt;
            {
                services.AddSingleton&amp;lt;LegacyPaymentService&amp;gt;(); // Serviço legado

                // Registra o Adapter
                services.AddSingleton&amp;lt;PaymentAdapter&amp;gt;(); 
                services.AddSingleton&amp;lt;IPaymentProcessor&amp;gt;(provider =&amp;gt; 
                    provider.GetRequiredService&amp;lt;PaymentAdapter&amp;gt;());

                // Adiciona o LoggingDecorator automaticamente com Scrutor
                services.Decorate&amp;lt;IPaymentProcessor, LoggingDecorator&amp;gt;();

                // Registra o Worker Service
                services.AddHostedService&amp;lt;PaymentWorker&amp;gt;(); 
                services.AddLogging(); 
            })
            .Build();

        host.Run();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📌 Estrutura de Pastas&lt;/p&gt;

&lt;p&gt;Aqui está a estrutura do projeto para manter tudo organizado:&lt;/p&gt;

&lt;p&gt;📂 PaymentProcessorApp&lt;br&gt;
│── 📂 Adapters&lt;br&gt;
│   └── PaymentAdapter.cs&lt;br&gt;
│── 📂 Decorators&lt;br&gt;
│   └── LoggingDecorator.cs&lt;br&gt;
│── 📂 Interfaces&lt;br&gt;
│   └── IPaymentProcessor.cs&lt;br&gt;
│── 📂 Services&lt;br&gt;
│   └── LegacyPaymentService.cs&lt;br&gt;
│── 📂 Workers&lt;br&gt;
│   └── PaymentWorker.cs&lt;br&gt;
│── Program.cs&lt;br&gt;
│── PaymentProcessorApp.csproj&lt;/p&gt;

&lt;p&gt;🚀 Benefícios dessa Abordagem&lt;/p&gt;

&lt;p&gt;✅ Código modular e reutilizável → Podemos adicionar novos IPaymentProcessor ou decorators sem alterar a implementação principal.&lt;br&gt;
✅ Extensibilidade → Podemos criar mais decorators, como um validador ou auditoria.&lt;br&gt;
✅ Baixo acoplamento → Usando DI e Scrutor, evitamos dependências rígidas.&lt;br&gt;
✅ Facilidade de Testes → Podemos testar LoggingDecorator separadamente.&lt;/p&gt;

&lt;p&gt;Essa abordagem combina Adapter e Decorator Patterns com Injeção de Dependência, mantendo o código limpo, flexível e escalável.&lt;/p&gt;

&lt;p&gt;Se você gostou, deixe um comentário ou compartilhe! 🚀🔥&lt;/p&gt;




</description>
      <category>csharp</category>
      <category>designpatterns</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Adapter Pattern em C# com Injeção de Dependência e Worker Service</title>
      <dc:creator>Luciano Azevedo</dc:creator>
      <pubDate>Sun, 02 Feb 2025 20:36:38 +0000</pubDate>
      <link>https://forem.com/oluciaano/adapter-pattern-em-c-com-injecao-de-dependencia-e-worker-service-4f61</link>
      <guid>https://forem.com/oluciaano/adapter-pattern-em-c-com-injecao-de-dependencia-e-worker-service-4f61</guid>
      <description>&lt;p&gt;🚀 Aplicando o Adapter Pattern em C# com Injeção de Dependência e Worker Service&lt;/p&gt;

&lt;p&gt;📌 Introdução&lt;/p&gt;

&lt;p&gt;Ao trabalhar com sistemas legados, é comum encontrar APIs ou serviços que não seguem as interfaces modernas do nosso código. Em vez de modificar diretamente esses sistemas, podemos usar o Adapter Pattern para fazer a integração de forma elegante.&lt;/p&gt;

&lt;p&gt;Neste artigo, vou mostrar como implementar o Adapter Pattern em C#, usando Injeção de Dependência (DI) e um Worker Service para simular um processo contínuo.&lt;/p&gt;




&lt;p&gt;🎯 O que é o Adapter Pattern?&lt;/p&gt;

&lt;p&gt;O Adapter Pattern é um padrão estrutural que permite que objetos com interfaces incompatíveis trabalhem juntos. Ele age como um intermediário, convertendo a interface de uma classe para outra esperada pelo sistema.&lt;/p&gt;

&lt;p&gt;📌 Quando usar?&lt;/p&gt;

&lt;p&gt;✅ Quando precisamos integrar APIs ou bibliotecas legadas que não podem ser alteradas.&lt;br&gt;
✅ Quando queremos manter um código desacoplado e flexível.&lt;br&gt;
✅ Quando temos diferentes implementações que precisam seguir um mesmo contrato.&lt;/p&gt;



&lt;p&gt;🛠️ Implementação&lt;/p&gt;

&lt;p&gt;Vamos construir um exemplo onde temos um sistema de pagamentos legados e queremos integrá-lo a um Worker Service que processa pagamentos periodicamente.&lt;/p&gt;

&lt;p&gt;🏗️ 1️⃣ Criamos a interface moderna IPaymentProcessor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface IPaymentProcessor
{
    void ProcessPayment(decimal amount);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🏗️ 2️⃣ Criamos o serviço legado LegacyPaymentService&lt;/p&gt;

&lt;p&gt;Este é um serviço que já existe e que queremos reutilizar, mas ele usa uma interface diferente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public sealed class LegacyPaymentService
{
    public void MakePayment(string amount)
    {
        Console.WriteLine($"Processing payment of {amount} via legacy system.");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🏗️ 3️⃣ Criamos o Adapter PaymentAdapter&lt;/p&gt;

&lt;p&gt;Aqui adaptamos LegacyPaymentService para seguir a interface IPaymentProcessor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public sealed class PaymentAdapter : IPaymentProcessor
{
    private readonly LegacyPaymentService _legacyPaymentService;

    public PaymentAdapter(LegacyPaymentService legacyPaymentService)
    {
        _legacyPaymentService = legacyPaymentService;
    }

    public void ProcessPayment(decimal amount)
    {
        string amountString = amount.ToString("F2");
        _legacyPaymentService.MakePayment(amountString);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🏗️ 4️⃣ Criamos o Worker Service PaymentWorker&lt;/p&gt;

&lt;p&gt;Nosso Worker será responsável por chamar o IPaymentProcessor periodicamente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;

public class PaymentWorker : BackgroundService
{
    private readonly ILogger&amp;lt;PaymentWorker&amp;gt; _logger;
    private readonly IPaymentProcessor _paymentProcessor;

    public PaymentWorker(ILogger&amp;lt;PaymentWorker&amp;gt; logger, IPaymentProcessor paymentProcessor)
    {
        _logger = logger;
        _paymentProcessor = paymentProcessor;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Iniciando processamento de pagamento...");

            _paymentProcessor.ProcessPayment(100.50m); // Simulando pagamento de R$100,50

            _logger.LogInformation("Pagamento processado com sucesso!");

            await Task.Delay(5000, stoppingToken); // Executa a cada 5 segundos
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🏗️ 5️⃣ Configuramos a Injeção de Dependência no Host&lt;/p&gt;

&lt;p&gt;Agora precisamos configurar os serviços no Host do Worker Service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

class Program
{
    static void Main(string[] args)
    {
        var host = Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =&amp;gt;
            {
                services.AddSingleton&amp;lt;LegacyPaymentService&amp;gt;(); // Serviço legado
                services.AddSingleton&amp;lt;IPaymentProcessor, PaymentAdapter&amp;gt;(); // Adapter
                services.AddHostedService&amp;lt;PaymentWorker&amp;gt;(); // Worker Service
                services.AddLogging(); // Logs
            })
            .Build();

        host.Run();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;✅ O que aprendemos?&lt;/p&gt;

&lt;p&gt;✔ Como usar o Adapter Pattern para conectar serviços legados a um código moderno.&lt;br&gt;
✔ Como estruturar Injeção de Dependência (DI) para desacoplar o código.&lt;br&gt;
✔ Como criar um Worker Service que processa tarefas periodicamente.&lt;/p&gt;




&lt;p&gt;🚀 Conclusão&lt;/p&gt;

&lt;p&gt;O Adapter Pattern é uma solução poderosa para integrar serviços sem alterar o código legado. Combinado com Injeção de Dependência e Worker Services, ele nos permite construir sistemas escaláveis e bem estruturados.&lt;/p&gt;

&lt;p&gt;E você? Já usou esse padrão em algum projeto? Deixe um comentário! 🚀&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>designpatterns</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
