.NET  - Migrando para o .NET 10


 Neste artigo estou republicando material da Microsoft que apresenta uma visão geral de como fazer a migração para o .NET 10.

O .NET 10 Preview 7 já está disponível desde 12 de agosto de 2025. O lançamento final de suporte de longo prazo (LTS) está programado para novembro de 2025.



Atualizar para o .NET 10 não é apenas mudar um número de versão — é uma oportunidade de repensar sua arquitetura, eliminar a dívida técnica e aproveitar as mais recentes melhorias de tempo de execução e da linguagem C# para ter melhor performance, segurança e produtividade do desenvolvedor.

Este guia indica cada fase — avaliação, migração de código, ajuste de performance, observabilidade e estratégia de lançamento — com explicações equilibradas e trechos de código práticos.

Esta não é apenas "mais uma atualização anual". É um lançamento que faz o .NET parecer mais poderoso — e mais agradável — para a construção de aplicativos modernos. 

1 - Avaliação e Planejamento

Comece com uma visão abrangente e detalhada do seu ambiente para minimizar surpresas durante a migração.

a- Catalogue todos os projetos, bibliotecas compartilhadas e serviços de segundo plano.

b- Use dotnet list package --outdated para identificar dependências desatualizadas do NuGet e suas versões mais recentes compatíveis com o .NET 10.

c- Documente os requisitos da plataforma (versões do sistema operacional, imagens base de contêineres, restrições de infraestrutura).

d- Marque os aplicativos por criticidade e prazos de suporte para priorizar serviços de alto risco.

Um inventário completo garante que você não esquecerá de cargas de trabalho legadas ou dependências obscuras que poderiam prejudicar a atualização.

2- Consistência do Arquivo de Projeto e do SDK

Alinhe cada projeto e estação de trabalho do desenvolvedor com o .NET 10 para evitar o famoso problema de “na minha máquina funciona”.

Em cada .csproj, atualize:

 <PropertyGroup>
   <TargetFramework>net10.0</TargetFramework>
  <Nullable>enable</Nullable>
  <ImplicitUsings>enable</ImplicitUsings>
  <PublishTrimmed>true</PublishTrimmed>
  <TieredPGO>true</TieredPGO>
</PropertyGroup>

Comite um global.json na raiz da solução:

{
  "sdk": {
    "version": "10.0.100",
    "rollForward": "latestFeature"
  }
}

Atualize as IDEs (Visual Studio 2025, JetBrains Rider, VS Code) e garanta que os agentes de build referenciem o mesmo SDK.

Bloquear seu SDK e as configurações do projeto garante que cada build — local ou de CI — tenha como alvo comportamentos de runtime idênticos.

3- Evoluindo a Sua Camada de API

Aproveite as melhorias da API Mínima do .NET 10 sem comprometer a estrutura em aplicativos maiores.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Middleware padrão
app.UseSwagger();
app.UseSwaggerUI();
app.UseHttpsRedirection();
app.MapGet("/status", () => Results.Ok("Healthy"))
   .WithName("GetStatus")
   .WithOpenApi();
app.Run();

As APIs Mínimas podem coexistir com Controllers tradicionais e Razor Pages. Use-as para pequenos microsserviços ou protótipos de recursos, mas mantenha abordagens em camadas (Controllers, Services, Repositories) em soluções monolíticas ou corporativas.

4- Melhorias de Performance e Tempo de Execução

O .NET 10 introduz refinamentos em JIT, GC e otimizações em camadas — meça cada mudança.

   - PGO em Camadas (Tiered PGO): Aquece métodos "quentes" mais rapidamente nas primeiras execuções. Ativado via <TieredPGO>true</TieredPGO>.
   - Ajuste de GC: Em ambientes com contêineres, configure:

env:
  - name: DOTNET_GCServer
    value: "1"
  - name: COMPlus_GCHeapHardLimit
    value: "2147483648"

    -   Span<T> e Pipelines: Substitua buffers de array de bytes por Span<byte> e System.IO.Pipelines para reduzir alocações.

Sempre faça benchmarks com o BenchmarkDotNet, comparando métricas de "antes" e "depois" para garantir que as otimizações tenham um impacto real.

5 - Migração da Camada de Dados e EF Core

Refatore seu DbContext e as configurações do modelo para aproveitar os novos recursos do EF Core 8.

public class AppDbContext : DbContext
{
    public DbSet<Pedido> Pedidos { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Pedido>(e =>
        {
            e.Property(o => o.Valor).HasPrecision(18, 2);
            e.HasIndex(o => new { o.ClienteId, o.CriadoEm });
            e.ToTable("Pedidos");
        });
    }
}

-  Use o ExecuteUpdateAsync para operações em massa para evitar as penalidades de change-tracking.
- Gere modelos compilados com dotnet ef dbcontext optimize para reduzir a sobrecarga de inicialização em esquemas grandes.

Essas práticas minimizam a latência de tempo de execução e a ocupação de memória em serviços com uso intensivo de dados.

6 -  Compilação AOT e IL Trimming

AOT e trimming podem gerar melhorias drásticas na inicialização para ferramentas de CLI ou serviços de borda — mas aborde com cautela.

<PropertyGroup>
  <PublishAot>true</PublishAot>
  <PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
<ItemGroup>
  <TrimmerRootDescriptor Include="TrimmerRoots.xml" />
</ItemGroup>
<linker>
  <assembly fullname="MyApp">
    <type fullname="MyApp.ReflectionType" preserve="all" />
  </assembly>
</linker>

- Use AOT apenas em cargas de trabalho com uso intenso de CPU ou que exijam baixa latência.
- Use descritores de raiz para preservar quaisquer tipos que dependam de reflection.
- Sempre teste builds trimados com seu pacote de testes completo para detectar metadados ausentes.

7. Observabilidade e Resiliência

Integre logging estruturado, rastreamento distribuído e tratamento robusto de falhas desde o primeiro dia.

builder.Host.UseSerilog((ctx, lc) =>
    lc.ReadFrom.Configuration(ctx.Configuration));
builder.Services.AddOpenTelemetryTracing(tb =>
    tb.AddAspNetCoreInstrumentation()
      .AddHttpClientInstrumentation()
      .AddSqlClientInstrumentation()
      .UseOtlpExporter());

Empregue políticas do Polly para retentativas, disjuntores e bulkheads em cada chamada externa.

Exponha endpoints de saúde e prontidão totalmente instrumentados:

builder.Services.AddHealthChecks()
       .AddSqlServer(connString);
app.MapHealthChecks("/health/live");
app.MapHealthChecks("/health/ready");

A telemetria abrangente e a arquitetura resiliente reduzem drasticamente o MTTR (Tempo Médio para Reparo) em incidentes de produção.

8 - Testes Automatizados e Portões de Qualidade

Um pacote de testes robusto e a análise estática evitam inúmeras dores de cabeça no futuro.

 - Testes de Unidade para lógica pura, visando 100% de cobertura em módulos críticos.
 - Testes de Integração usando Testcontainers ou provedores em memória para ambientes realistas.
 - Testes de Contrato (Pact) para acordos de serviço para serviço.
 - Análise Estática: Adicione analisadores em seu .csproj:

<AnalysisLevel>latest</AnalysisLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

Incorpore essas verificações em seu pipeline de CI para evitar regressões antes que elas cheguem às branches principais.

9 - CI/CD e Melhores Práticas de Implantação

Simplifique seu pipeline para lançamentos consistentes e seguros.

steps:
- uses: actions/checkout@v4
- name: Setup .NET 10
  uses: actions/setup-dotnet@v4
  with:
    dotnet-version: 10.0.x
- name: Restore & Build
  run: dotnet build --configuration Release
- name: Test & Coverage
  run: dotnet test --collect:"XPlat Code Coverage"
- name: Publish
  run: dotnet publish src/MyApp/MyApp.csproj \
             -c Release \
             -o ./publish \
             /p:PublishTrimmed=true

- Use builds Docker de múltiplos estágios com um usuário não-root e geração de SBOM.
- Aplique estratégias Blue-Green ou Canary para lançamentos sem tempo de inatividade.
- Automatize o gerenciamento de segredos via integrações com Key Vault ou HashiCorp Vault.

Isso garante que cada lançamento seja repetível, seguro e observável.

10 - Estratégia de Lançamento e Feature Flags

Uma migração gradual reduz o raio de impacto e ajuda a validar cada mudança.

 - Feature Flags: Envolva novos caminhos de código do .NET 10 e alterne-os em tempo de execução.
 - Canary Deployments: Direcione uma pequena porcentagem do tráfego de produção para a nova versão.
 - Planos de Reversão: Mantenha um procedimento de reversão claro e automatizado — por exemplo, alternar flags ou reverter gráficos do Helm.

Um lançamento controlado gera confiança e dá tempo para a sua equipe lidar com casos de ponta inesperados.

Assim, o .NET 10 Preview 7 (lançado em 12 de agosto de 2025) dá a você uma vantagem inicial sobre o lançamento oficial do LTS, agendado para novembro de 2025. Esta atualização é muito mais do que um simples aumento de versão — é uma oportunidade estratégica para:

Eliminar a dívida técnica acumulada ativando tipos de referência anuláveis, removendo IL não utilizado e adotando implicit usings.

Desbloquear otimizações de tempo de execução como PGO em camadas, políticas de GC refinadas e compilação AOT opcional para inicialização mais rápida e ocupação de memória menor.

Aproveitar as melhorias do C# 13, APIs mínimas e padrões aprimorados do EF Core para escrever um código mais limpo e fácil de manter.

Ao iniciar sua migração na fase de pré-visualização, você pode validar dependências críticas, fazer benchmarks de ganhos de performance reais e refinar seus processos de CI/CD antes do lançamento oficial. Adote feature flags, implantações canary e observabilidade abrangente para mitigar riscos e garantir um lançamento suave.

Não espere até que as janelas de suporte fechem — comece a experimentar com o .NET 10 hoje e posicione sua equipe para a próxima era de performance, segurança e produtividade do desenvolvedor.

E estamos conversados...  

"E, como eles não se importaram de ter conhecimento de Deus, assim Deus os entregou a um sentimento perverso, para fazerem coisas que não convêm;"
Romanos 1:28

Referências:


José Carlos Macoratti