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 artigoAs 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 .- 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.
- Repository . . List Repository T[] ValueObject Entities. Repository InfrastructureService InfrastructureService Repository. : Logger, EmailSender.
- 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:- Defina a interface que implementará a infraestrutura e interagirá com ela.
- 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:- Tudo é dividido em pastas.
- 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.