Je bedrijf draait nog op .NET Framework 4.x. De codebase is tien jaar oud, misschien ouder. Iedereen is het erover eens dat het naar .NET 8 of 9 moet. Niemand wil degene zijn die begint.
Begrijpelijk. Framework-migraties zijn saai, riskant en ondankbaar. Je bouwt niks nieuws — je herschrijft wat al werkt, en hoopt dat je onderweg niks breekt.
Maar ik gebruik Claude Code om te helpen bij dit soort migraties, en het maakt een uitzichtloos project behapbaar. Zo pak ik het aan.
Stap 1: Inventarisatie — weet wat je hebt
Voordat je ook maar een regel wijzigt, moet je begrijpen wat je hebt. Vraag Claude Code om je solution te analyseren:
“Scan deze solution. Maak een lijst van alle projecten, hun target frameworks, NuGet-pakketten en Framework-specifieke APIs zoals System.Web, WCF of COM interop.”
Claude Code gaat door je .csproj-bestanden, packages.config-bestanden en broncode. Het bouwt een dependency-overzicht dat je normaal dagen kost om in een spreadsheet te zetten.
De uitkomst vertelt je welke projecten eenvoudig zijn (class libraries zonder Framework-afhankelijkheden) en welke pijn gaan doen (ASP.NET WebForms, WCF-services, alles wat System.Web aanraakt).
Alleen deze stap bespaart je al een week handmatig inventariseren.
Stap 2: Bepaal het migratiepad
Big bang of incrementeel? Dat hangt af van je solution-structuur, en Claude Code kan je helpen kiezen.
Vraag: “Gegeven deze afhankelijkheden tussen projecten, wat is de migratievolgorde? Welke projecten kan ik onafhankelijk migreren?”
Claude Code brengt de dependency-graph in kaart en stelt een bottom-up aanpak voor: begin met gedeelde libraries die geen Framework-afhankelijkheden hebben, en werk dan omhoog naar de web- en serviceprojecten.
Voor de meeste echte solutions is incrementeel het juiste antwoord. Je migreert een project tegelijk, houdt de solution buildend en levert tussentijds op. Big bang werkt alleen als je solution klein is of als je geniet van een feature-freeze van drie maanden.
Stap 3: Converteer naar SDK-style projectbestanden
Hier blinkt Claude Code echt uit. Oude .csproj-bestanden zijn XML-nachtmerries — honderden regels die elk .cs-bestand apart opsommen. SDK-style projectbestanden zijn schoon.
Vraag Claude Code om een projectbestand te converteren, en het transformeert dit:
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<PropertyGroup>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<OutputType>Library</OutputType>
<AssemblyName>MyApp.Core</AssemblyName>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, ...">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Models\User.cs" />
<Compile Include="Models\Order.cs" />
<Compile Include="Services\UserService.cs" />
<!-- 200 meer regels -->
</ItemGroup>
</Project>
Naar dit:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>
Van 50+ regels naar 12. Claude Code handelt de packages.config naar PackageReference-conversie af, verwijdert de expliciete bestandsverwijzingen (SDK-style projecten gebruiken globbing) en schrapt de boilerplate-imports.
Stap 4: Vervang verouderde APIs
Dit is het saaie deel van elke migratie. Framework-specifieke APIs die niet bestaan in modern .NET. Claude Code handelt de gangbare patronen goed af.
HttpContext en System.Web:
// Voor: .NET Framework
var userId = HttpContext.Current.Session["UserId"]?.ToString();
var ip = HttpContext.Current.Request.UserHostAddress;
// Na: .NET 8 — inject IHttpContextAccessor
public class UserService(IHttpContextAccessor httpContextAccessor)
{
public string? GetUserId() =>
httpContextAccessor.HttpContext?.Session.GetString("UserId");
public string? GetClientIp() =>
httpContextAccessor.HttpContext?.Connection.RemoteIpAddress?.ToString();
}
ConfigurationManager:
// Voor: .NET Framework
var connectionString = ConfigurationManager.ConnectionStrings["DefaultDb"].ConnectionString;
var apiKey = ConfigurationManager.AppSettings["ExternalApiKey"];
// Na: .NET 8 — gebruik IConfiguration of het options pattern
public class ApiSettings
{
public string ExternalApiKey { get; set; } = "";
}
// In Program.cs:
builder.Services.Configure<ApiSettings>(builder.Configuration.GetSection("Api"));
Claude Code doet geen simpele zoek-en-vervang. Het begrijpt de patronen en herschrijft ze idiomatisch. Het stelt het options pattern voor waar dat past, en injecteert IConfiguration waar een snelle fix genoeg is.
Stap 5: Migreer dependency injection
Als je Framework-project Ninject, Unity of Autofac gebruikt, moet je een keuze maken. Modern .NET heeft ingebouwde DI die de meeste scenario’s dekt.
Claude Code kan je DI-registraties herschrijven:
// Voor: Ninject
kernel.Bind<IUserRepository>().To<SqlUserRepository>().InRequestScope();
kernel.Bind<IOrderService>().To<OrderService>().InTransientScope();
kernel.Bind<ICacheService>().To<RedisCacheService>().InSingletonScope();
// Na: Ingebouwde Microsoft DI
builder.Services.AddScoped<IUserRepository, SqlUserRepository>();
builder.Services.AddTransient<IOrderService, OrderService>();
builder.Services.AddSingleton<ICacheService, RedisCacheService>();
De lifetime-mapping is rechttoe rechtaan: InRequestScope wordt AddScoped, InTransientScope wordt AddTransient, InSingletonScope wordt AddSingleton. Claude Code doet dit betrouwbaar.
Bij complexe Autofac-registraties — modules, decorators, keyed services — wordt het lastiger. Claude Code kan het meeste aan, maar controleer zorgvuldig. Of houd gewoon Autofac. Dat werkt prima met .NET 8.
Stap 6: Configuratiemigratie
De overstap van web.config XML naar appsettings.json is nog een taak die Claude Code goed afhandelt. Vraag het je configuratie te converteren, en het herstructureert de data:
{
"ConnectionStrings": {
"DefaultDb": "Server=.;Database=MyApp;Trusted_Connection=true"
},
"Api": {
"ExternalApiKey": "your-key-here",
"Timeout": 30
},
"Logging": {
"LogLevel": {
"Default": "Information"
}
}
}
Het genereert ook de bijbehorende Program.cs-setup met het minimal hosting model. Geen Startup.cs meer met ConfigureServices en Configure — gewoon een schone Program.cs.
Wat Claude Code niet kan
Laat me eerlijk zijn over de grenzen.
WCF-services. Als je WCF-services host (niet alleen consumeert), is er geen schoon migratiepad. CoreWCF bestaat, maar het is een compatibiliteitslaag, geen echte migratie. Claude Code kan helpen beoordelen welke services je als minimal APIs kunt herschrijven, maar de architectuurbeslissingen zijn aan jou.
ASP.NET WebForms. Er is geen geautomatiseerd pad van .aspx-pagina’s met code-behind naar Razor Pages of Blazor. Claude Code kan individuele pagina’s helpen herschrijven, maar het kan je ViewState-afhankelijke page lifecycle niet automatisch doorgronden. Dit is een herschrijving, geen migratie.
COM interop. Als je applicatie COM-componenten aanroept, kan Claude Code die afhankelijkheden identificeren maar ze niet magisch laten werken op Linux of in containers. Je moet kiezen: Windows houden, een .NET-alternatief zoeken, of de COM-afhankelijkheid isoleren.
Custom build targets en MSBuild-magie. Sommige Framework-projecten hebben uitgebreide MSBuild-aanpassingen. Claude Code handelt standaardpatronen af maar mist mogelijk custom BeforeCompile-targets of conditionele property groups die iets onverwachts doen.
Realistische verwachtingen
Een migratie als deze is geen weekendproject. Dit is wat ik in de praktijk zie:
- Class libraries zonder Framework-afhankelijkheden: 30 minuten per project met Claude Code.
- Libraries met ConfigurationManager of System.Web: 1-2 uur per project.
- ASP.NET MVC-projecten: een hele dag, inclusief routing- en middleware-wijzigingen.
- WCF-services: dagen tot weken, afhankelijk van complexiteit. Claude Code helpt, maar dit is vooral handmatig architectuurwerk.
De eerlijke waarheid: Claude Code maakt van een migratie van zes maanden een migratie van twee maanden. Het elimineert niet het werk — het elimineert de saaie delen. De dependency-analyse, de csproj-conversies, de API-vervangingen, de DI-herschrijvingen. Dat is 70% van het werk, en Claude Code doet het goed.
De overige 30% — architectuurbeslissingen, edge cases testen, omgaan met WCF en WebForms — dat blijft bij jou.
Waar te beginnen
Probeer niet alles tegelijk te migreren. Pak de kleinste, meest onafhankelijke library in je solution. Vraag Claude Code om het te converteren. Build. Run de tests. Fix wat breekt.
Dan de volgende. En de volgende.
Voor je het weet draait de helft van je solution op .NET 8 en zijn de Framework-projecten de uitzondering, niet de regel. Dat is het moment waarop de migratie niet meer onmogelijk voelt, maar onvermijdelijk.
Sta je voor een .NET Framework-migratie? Of zit je er middenin? Ik hoor graag waar je tegenaan loopt. Neem contact op via de contactpagina.