Brevemente sobre onde colocar o Repositório na Onion Architeckture e no DDD


Olá, Habr. Quero falar sobre onde, na figura acima, colocamos o repositório. Um pouco mais sobre DIP, IoC e estrutura do projeto. Existe uma abordagem padrão segundo a qual as interfaces IRepository devem ser evitadas na camada de domínio para DomainServices e a implementação em Infraestrutura. Aqui estamos falando de repositórios padrão, que são apenas uma coleção abstrata de objetos que não sabem sobre transações e UnitOfWork e assim por diante (por exemplo, IList e sua versão genérica são a interface típica de um repositório abstrato). Pessoalmente, não concordo com ele, porque geralmente os repositórios estão repletos de comportamentos específicos a um aplicativo específico, então coloquei suas interfaces no ApplicationServices. A implementação do curso permanece na camada Infraestrutura. Se você estiver interessado, bem-vindo ao gato.

Muitas vezes, muitos ficam confusos com a imagem antiga de Robert Martin:

ele tem as palavras no artigo
As entidades encapsulam as regras de negócios em toda a empresa. Uma entidade pode ser um objeto com métodos ou um conjunto de estruturas e funções de dados. Não importa, desde que as entidades possam ser usadas por muitos aplicativos diferentes na empresa.

Portanto, acontece que ele simplesmente atribui DomainServices à camada Entities. Bem, UseCases == ApplicationServices. Gateways == UserPepository, EmailService, Logger. Leia mais aqui .

  1. Serivice é qualquer classe sem estado. InfrastructureService é um arquivo anticorrupção que o isola do sistema de arquivos, da biblioteca para trabalhar com SMTP e, é claro, do ORM ou da biblioteca para trabalhar com o banco de dados, etc.
  2. Repository . . List Repository T[] ValueObject Entities. Repository InfrastructureService InfrastructureService Repository. : Logger, EmailSender.
  3. Repository InfrastructureService - EmailSender EmailService, FileService ( File.Open(… ) . .) .


Para entender onde colocar abstrações, precisamos pensar em Inversão de Dependência e Inversão de Controle. Segundo eles, nosso ApplicationService pode usar a infraestrutura, não sei qual é a sua implementação de maneiras como:
  1. Defina a interface que implementará a infraestrutura e interagirá com ela.
  2. Apenas aceite delegados como Action e Func.


Via interfaces:

    interface IRepository
    {
        int Get();
    }

    class ApplicationService
    {
        private readonly IRepository _repository;

        public ApplicationService(IRepository repository)
        {
            _repository = repository;
        }

        public int GetInt() => _repository.Get();
    }

Através dos delegados:

    class ApplicationService
    {
        private readonly Func<int> _getIntFromDb;

        public ApplicationService(Func<int> getIntFromDb)
        {
            _getIntFromDb = getIntFromDb;
        }

        public int GetInt() => _getIntFromDb();
    }

Agora, sobre como estruturar o código. Há dois casos a serem considerados:
  1. Tudo é dividido em pastas.
  2. Tudo é dividido em bibliotecas.

Detalhes da terminologia podem ser encontrados aqui .

Pastas dentro do mesmo aplicativo


Exemplo de código SnakeGame


Por bibliotecas


Colocamos as interfaces InfrastructureServices (IRepository) na biblioteca ApplicationServices e a implementação (Repository) na biblioteca Infrastructure.



A imagem final de um artigo de uma pessoa com muito mais experiência em desenvolvimento do que a minha e que também acha que o IRepository deve ser colocado na Camada de Aplicativos para ApplicationServices (as implementações do Repositório também possuem Infraestrutura).


achados


A interface de serviços de infraestrutura (IRepository, IEmailSender) pode ser colocada na biblioteca ApplicationServices.dll e sua implementação específica (Repository, EMailSender) na biblioteca Infrastructure.dll.

All Articles