Monorepositório com C#: organização de código na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Monorepositório com C#: organização de código na prática



Monorepositório (monorepo) é uma abordagem para gerenciamento de código-fonte onde todos os projetos de uma empresa ou equipe são armazenados em um único repositório. No mundo C# e .NET, essa abordagem está se tornando cada vez mais popular devido à simplificação do desenvolvimento colaborativo, unificação de versões de dependências e CI/CD centralizado. No entanto, sem uma organização adequada do código, um monorepositório pode se transformar em caos. Neste artigo, vamos explorar técnicas práticas para organizar código C# em um monorepositório: desde a estrutura de pastas até a configuração de build.



1. Estrutura de pastas: a base da ordem



O primeiro passo para um monorepositório bem-sucedido é uma hierarquia de diretórios bem planejada. Recomenda-se seguir uma convenção onde cada projeto fica em uma pasta separada, e os componentes comuns são colocados em src/shared. Exemplo de estrutura básica:



/monorepo├── src/│   ├── shared/│   │   ├── CommonLib/          # Utilitários comuns, DTOs, interfaces│   │   └── LoggingLib/         # Logging│   ├── services/│   │   ├── AuthService/        # Microsserviço de autenticação│   │   └── OrderService/       # Microsserviço de pedidos│   └── apps/│       ├── WebApi/             # Aplicação web principal│       └── ConsoleApp/         # Ferramenta de console├── tests/│   ├── unit/│   │   ├── CommonLib.Tests/│   │   └── AuthService.Tests/│   └── integration/│       └── IntegrationTests/├── docs/├── scripts/├── .gitignore├── Directory.Build.props└── global.json


Pontos-chave:

  • src/ — código-fonte de todos os projetos.
  • shared/ — bibliotecas usadas por vários projetos.
  • services/ — microsserviços ou módulos.
  • apps/ — aplicações finais (Web API, Console, Blazor).
  • tests/ — testes, isolados do código-fonte.


Essa estrutura facilita encontrar código, evitar dependências cíclicas e simplifica a configuração de CI/CD.



2. Gerenciamento de projetos com Directory.Build.props



Em um monorepositório, frequentemente surge a necessidade de definir configurações comuns para todos os projetos: versões do .NET, pacotes compartilhados, regras de análise de código. Em vez de duplicar em cada .csproj, use o arquivo Directory.Build.props na raiz do repositório. Exemplo:



<Project>  <PropertyGroup>    <TargetFramework>net8.0</TargetFramework>    <ImplicitUsings>enable</ImplicitUsings>    <Nullable>enable</Nullable>    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>  </PropertyGroup>

<ItemGroup> <PackageReference Include="SonarAnalyzer.CSharp" Version="9.*" /> </ItemGroup></Project>


Agora, cada projeto filho herda automaticamente essas configurações. Se precisar sobrescrever para um projeto específico, basta adicionar as propriedades no .csproj dele — elas têm prioridade.



Adicionalmente, você pode criar um Directory.Build.targets para objetivos de build comuns (por exemplo, copiar arquivos após o build).



3. Gerenciamento de dependências: abordagem centralizada



Um dos principais problemas de um monorepositório é o conflito de versões de pacotes. No .NET 8, foi introduzido suporte nativo para gerenciamento centralizado de pacotes (Central Package Management, CPM). Para isso, crie o arquivo Directory.Packages.props na raiz:



<Project>  <PropertyGroup>    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>  </PropertyGroup>  <ItemGroup>    <PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />    <PackageVersion Include="Serilog" Version="3.1.1" /&g                

Blogs

Book Recommendations