Pular para conteúdo

Implementação das funcionalidades

O núcleo funcional da implementação está organizado entre os projetos Magna.IndicePmo.Application e Magna.IndicePmo.Domain, Magna.IndicePmo.Application.Contracts e Magna.IndicePmo.Domain.Shared.

Núcleo funcional

Application.Contracts e Domain.Shared

  • Descreve os DTO, configurações e serviços de aplicação que interfaceiam com a camada pública de API.
  • Auxiliares para mapeamento de erros e códigos de erros padronizados.

Application

  • Recebe como parâmetros de entrada, DTO organizados em Magna.IndicePmo.Application.Contracts.
  • Organiza as operações funcionais, implementadas Magna.IndicePmo.Domain.
  • Recruta serviços de aplicação, como mapeamentos e repositórios de persistência.

Nesta POC, utilizaremos apenas uma classe do tipo ApplicationService, denominada GestorAvaliacoesAppService. Classes do tipo Serviços da Aplicação, na terminologia do DDD, são artefatos capazes de coordenar operações entre um ou mais serviços de domínio e recursos de infraestrutura e persistência inerentes à aplicação.

Alguns pontos importantes:

  • É esta camada camada que responde às requisições provenientes da API pública do nosso serviço (representada por Magna.IndicePmo.HttpApi).
  • As operações realizadas com este serviço recebem DTO como entradas de dados e retornam DTO como respostas.
  • Utiliza-se um wrapper baseado no Result Pattern ⧉. Esta é uma escolha para descrever resultados de operações sem o recurso excessivo de throw exception.
  • Embora GestorAvaliacoesAppService manipule as entities e aggregation roots do domínio, evitamos expor esses objetos para evitarmos problemas de lazy loading quando o contexto de obtenção de dados já foi encerrado.
  • Esta escolhas oneram o sistema em mais uma camada de mapeamento, implementada na classe utilitária IndicePmoApplicationAutoMapperProfile.

A estrutura geral de cada operação em GestorAvaliacoesAppService tem as seguintes etapas:

Estrutura de uma operação em GestorAvaliacoesAppService

Explicando:

  • Passo 1: Execução de uma operação de domínio. Neste caso, a obtenção de um registro de avaliação.
  • Passo 2: Mapeamento para DTO de uma situação de falha. Neste caso, registro não encontrado.
  • Passo 3: Execução de uma operação de domínio. Neste caso, a atualização do preenchimento de um registro.
  • Passo 4: Mapeamento para DTO do resultado da operação de atualização.

Domain

Uma única classe do tipo serviço de domínio, GestorAvaliacaoService.

Implementa as operações lógicas para:

  • Gestão dos templates de avaliação. Um para cada tipo de índice.
  • Criação de uma nova avaliação.
  • Modificação do score de cada item de avaliação.
  • Recálculo de score da avaliação.
  • Orquestração da gravação e leitura a partir de repositórios.
  • Representação de questoes e avaliações como entidades e aggregation roots, respectivamente. Bem como a lógica de inicialização destes objetos de domínio.

Adicionalmente, o diretório DataServices contém a especificação de repositórios e interfaces para realizar as rotinas de gravação, leitura, remoção de dados.

Data Services e repositórios na camada de domínio

Persistência dos dados

Nesta fase da implementação, é possível adiar a preocupação com a persistência concreta dos dados. Para isso, incluímos uma implementação in-memory para os serviços representados pela interface IAvaliacoesDataService diretamente no projeto de domínio.

Com efeito, retornaremos à persistência em base de dados na próxima seção.

Magna.IndicePmo.EntityFrameworkCore

Implementa as operações de DataServices para o banco de dados MySql. Retornaremos a esta implementação na próxima seção.

Interligação com HttpAPI

É possível retornar em HttpApi e interligá-lo com Magna.IndicePmo.Application.Contracts. Esta interligação completa a implementação necessária para o tráfego de dados entre a interface pública da API e o núcleo funcional.

  • As classes controladoras utilizarão as operações descritas no contrato IGestorAvaliacoesService.
  • Incluiremos a classe ApiV2AutoMapperProfile para realizar mapeamento entre os objetos do ViewModel e os objetos DTO do núcleo funcional.

Feito isso, uma operação típica em cada classe de controller terá a seguinte estrutura da seguinte forma:

alt text

Explicando:

  • Passo 1: Mapeamento do view model para um DTO.
  • Passo 2: Execução de uma operação funcional. Note-se que _appService é uma instância de IGestorAvaliacoesService.
  • Passo 3: Transformação do resultado da operação em um viewModel compatível com o contrato da API pública.

Neste momento, a nossa versão compilada agora é capaz de realizar as operações funcionais com nossa API e verificar a correção dos resultados.

Swagger - Consulta Índices

Na próxima etapa, interligaremos um front-end baseado em React com a nossa API.