.NET - Apresentando Domain Events - I


 Neste artigo vou apresentar o que são e como funcionam os Domain Events.

"Domain Events"
são eventos que ocorrem dentro do domínio de um aplicativo, representando algo significativo que aconteceu no sistema. Esses eventos são uma forma de comunicação entre diferentes partes do domínio, permitindo que objetos reajam a mudanças ou ações em outros objetos, sem a necessidade de acoplamento rígido entre eles. Eles encapsulam informações relevantes sobre o evento e podem ser ouvidos (ou assinados) por outras partes do sistema que desejam reagir a esses eventos.

Desta forma um evento de domínio é um objeto que representa algo significativo que aconteceu no domínio. Por exemplo, um cliente fez um pedido, um produto foi enviado ou um pagamento foi recebido. Um evento de domínio geralmente possui um nome, um timestamp e alguns dados relevantes e são usados para implementar explicitamente os efeitos colaterais de alterações em seu domínio.

Para que servem os Domain Events ?

Podemos dizer que os Domain Events servem para:

  1. Promover o desacoplamento: Eles permitem que objetos dentro do domínio reajam a eventos sem conhecer os detalhes de implementação de outros objetos. Isso promove um baixo acoplamento e facilita a manutenção e a evolução do código.
  2. Expressar intenções do domínio: Os eventos de domínio refletem eventos significativos no domínio de negócios, tornando o código mais expressivo e relacionado ao problema real que o software está resolvendo.
  3. Facilitar a consistência do domínio: Os eventos podem ser usados para manter a consistência entre diferentes agregados e objetos dentro do domínio, garantindo que eles reajam a mudanças de maneira apropriada.
  4. Permitir auditoria e rastreamento: Os eventos podem ser registrados para fins de auditoria e rastreamento, permitindo que você saiba o que aconteceu em seu sistema.

Vantagens dos eventos de domínio

Os eventos de domínio oferecem uma série de vantagens, incluindo:

Exemplo prático

Suponha que você tenha um aplicativo de comércio eletrônico que permite que os usuários façam pedidos. Quando um usuário faz um pedido, o sistema deve disparar um evento de domínio chamado PedidoEnviadoEvent . Esse evento pode conter informações como o ID do pedido, o ID do cliente e os detalhes do pedido.

O evento PedidoEnviadoEvent pode ser usado para implementar uma variedade de efeitos colaterais, como:

// Definição de um evento de domínio
public class PedidoEnviadoEvent
{
    public int PedidoId { get; }
    public PedidoEnviadoEvent(int pedidoId)
    {
        PedidoId = pedidoId;
    }
}
// Classe de um agregado (Pedido)
public class Pedido
{
    private List<ItemPedido> _itens = new List<ItemPedido>();
    public int Id { get; private set; }
    public IReadOnlyList<ItemPedido> Itens => _itens;
    public void Enviar()
    {
        // Lógica de envio do pedido
        // Disparar um evento de domínio quando o pedido é enviado
        DomainEvents.Raise(new PedidoEnviadoEvent(Id));
    }
}
// Classe para lidar com eventos de domínio
public static class DomainEvents
{
    public static event Action<object> OnEventRaised;
    public static void Raise(object domainEvent)
    {
        OnEventRaised?.Invoke(domainEvent);
    }
}
// Exemplo de assinante (listener) de um evento de domínio
public class NotificacaoPedidoEnviado
{
    public NotificacaoPedidoEnviado()
    {
        DomainEvents.OnEventRaised += HandlePedidoEnviado;
    }
    private void HandlePedidoEnviado(object domainEvent)
    {
        if (domainEvent is PedidoEnviadoEvent pedidoEnviadoEvent)
        {
            // Lógica para notificar sobre o envio do pedido
            Console.WriteLine($"Pedido {pedidoEnviadoEvent.PedidoId} foi enviado.");
        }
    }
} 

Entendendo o código:

Os ouvintes de eventos podem ser usados para reagir aos eventos de domínio. Aqui está um exemplo de um ouvinte de eventos que atualiza o status do pedido para "Pedido recebido":

public class PedidoStatusListener
{
    public void Handle(PedidoEnviadoEvent event)
    {
        // Atualiza o status do pedido
        var pedido = PedidoRepository.GetById(event.Id);
        pedido.Status = PedidoStatus.Recebido;
        PedidoRepository.Save(pedido);
    }
}

Este ouvinte pode ser registrado usando o código a seguir:


  // Registra o ouvinte de eventos
  EventBus.Register<PedidoEnviadoEvent>(new PedidoStatusListener());

 

Este é um exemplo simplificado, mas demonstra como os Domain Events podem ser usados para promover o desacoplamento e a expressividade do código no contexto de uma aplicação. Eles são especialmente úteis em cenários onde ações em um domínio podem afetar outros objetos ou partes do sistema.

Em outro artigo vou mostrar um exemplo prático usando os Domain Events.

"['Senhor'] O teu reino é um reino eterno; o teu domínio dura em todas as gerações."
Salmos 145:13

Referências:


José Carlos Macoratti