NetLift: Automatyczne narzędzie migracji .NET Framework
Przez ostatnie kilka lat prowadziłem kilkanaście migracji z .NET Framework do .NET 8+. Za każdym razem napotykałem ten sam problem: 60-80% pracy to mechaniczne, powtarzalne transformacje. Zmień using System.Web.Mvc na using Microsoft.AspNetCore.Mvc. Przekształć DbContext.Set<T>().Where() na async ToListAsync(). Zamień [ServiceContract] na gRPC service.
To żmudna praca, podatna na błędy. Więc zbudowałem narzędzie, które robi to za mnie - NetLift.
NetLift korzysta z Roslyn (kompilatora C#) do analizy drzew składniowych i przeprowadzania deterministycznych transformacji kodu. Nie ma tu AI, nie ma losowości. Tylko precyzyjna inżynieria kompilatorów i 1819 testów jednostkowych gwarantujących poprawność transformacji.
Co znajdziesz w tym artykule
- • Dlaczego zbudowałem to narzędzie (i czemu .NET Upgrade Assistant nie wystarczy)
- • Jak działa NetLift pod maską (Roslyn, drzewa składniowe, transformacje)
- • Co konkretnie jest migrowane (MVC, EF6, WCF, CQRS)
- • Prawdziwe migracje do przejrzenia (3 pull requesty z real-world applications)
- • Scoring pewności transformacji (jak ufać wynikom)
- • Ograniczenia i co NIE jest obsługiwane
- • Jak zacząć z NetLift (quick start)
01Dlaczego zbudowałem to narzędzie
Kiedy migrujesz aplikację .NET Framework, masz świetne oficjalne narzędzie: .NET Upgrade Assistant. Robi fantastyczną robotę z plikami projektów - aktualizuje .csproj, dodaje pakiety NuGet, zmienia target framework. To rozwiązuje może 20% problemu.
Pozostałe 80%? To twój kod źródłowy. Tysiące linii kontrolerów MVC 5, które trzeba przekształcić do ASP.NET Core. Setki zapytań Entity Framework 6, które powinny być async w EF Core. Kontrakty WCF, które musisz zamienić na gRPC albo REST API. Wzorce CQRS z przestarzałymi interfejsami MediatR.
Większość czasu w projekcie migracyjnym to mechaniczna praca nad kodem. Upgrade Assistant rozwiązuje pliki projektów, ale kod źródłowy trzeba przepisywać ręcznie. Na dużej aplikacji to tygodnie pracy.
Chciałem narzędzie, które zrobi te transformacje za mnie. Roslyn daje dostęp do drzew składniowych - mogę analizować i przepisywać kod programatycznie, z gwarancją poprawności składniowej.
Dlatego powstał NetLift. W kontekście przewodnika migracji .NET, NetLift zajmuje się właśnie tą najbardziej czasochłonną fazą - automatyczną transformacją kodu.
02Jak działa NetLift
NetLift to nie gloryfikowany find-and-replace. Każda transformacja przechodzi przez Roslyn: parsing, analiza drzew składniowych, transformacja, przepisanie.
Pipeline Transformacji NetLift
1. Parsing (Roslyn Compiler)
Twój kod C# jest parsowany do Syntax Tree - struktury danych reprezentującej każdy element kodu: klasy, metody, wyrażenia, atrybuty.
// Your code
public class ProductsController : Controller
{
[HttpGet]
public ActionResult Index() { }
}
// Roslyn Syntax Tree (simplified)
ClassDeclaration("ProductsController")
├─ BaseList: "Controller"
└─ MethodDeclaration("Index")
├─ Attribute("[HttpGet]")
└─ ReturnType("ActionResult")2. Analiza Semantic Model
NetLift analizuje semantykę - nie tylko składnię, ale i znaczenie. Jakie typy są używane? Skąd pochodzą using statements? Czy metoda jest async?
SemanticModel.GetTypeInfo(node)
→ System.Web.Mvc.Controller
// NetLift decision:
// "This is MVC5 controller, needs AspNetCore migration"3. Transformacja Syntaktyczna
NetLift przepisuje drzewo składniowe używając Roslyn Rewriters. Każda transformacja jest deterministyczna - ta sama input zawsze daje ten sam output.
public override SyntaxNode VisitClassDeclaration(
ClassDeclarationSyntax node)
{
if (InheritsFrom(node, "System.Web.Mvc.Controller"))
{
return node
.ReplaceToken("Controller", "ControllerBase")
.WithUsing("Microsoft.AspNetCore.Mvc");
}
return node;
}4. Code Generation
Przekształcone drzewo składniowe jest konwertowane z powrotem do kodu C#. Roslyn gwarantuje poprawność składniową - jeśli kompilacja przeszła, wynik jest valid C#.
// Transformed output
using Microsoft.AspNetCore.Mvc;
public class ProductsController : ControllerBase
{
[HttpGet]
public IActionResult Index() { }
}Dlaczego Roslyn, a nie AI?
LLM-y potrafią generować kod, ale wyniki nie są powtarzalne. Ten sam prompt może dać różny output. Przy migracji to nie do przyjęcia.
Migracja kodu musi być przewidywalna i powtarzalna. Nie mogę mieć sytuacji, gdzie ten sam kod migrowany dwa razy daje różne wyniki. Roslyn daje mi tę gwarancję. Każda transformacja jest deterministyczna i pokryta testami jednostkowymi.
03Co jest migrowane
NetLift pokrywa najczęstsze scenariusze migracji .NET Framework do .NET 8+. Skupiam się na aplikacjach biznesowych - tam gdzie migracja przynosi największy ROI.
| Kategoria | Co jest migrowane | Target Tech | Coverage |
|---|---|---|---|
| MVC 5 | Controllers, ActionResults, Filters, ModelState, ViewBag/ViewData, Routing attributes | ASP.NET Core MVC | 75-85% |
| Entity Framework 6 | DbContext, LINQ queries, Include/ThenInclude, sync to async conversion, configuration | EF Core 8 | 60-75% |
| WCF Services | [ServiceContract], [OperationContract], [DataContract], binding configurations | gRPC / ASP.NET Core API | 50-65% |
| CQRS Patterns | MediatR IRequest/IRequestHandler, Command/Query classes, Pipeline behaviors | Modern MediatR 12+ | 80-90% |
| Dependency Injection | Autofac/Unity/Ninject registration → Microsoft.Extensions.DependencyInjection | Built-in DI | 70-80% |
| Configuration | Web.config/App.config → appsettings.json, IConfiguration, Options pattern | IConfiguration | 65-75% |
Przykład: Migracja Kontrolera MVC 5
Before (MVC 5)
using System.Web.Mvc;
public class ProductsController : Controller
{
private readonly IProductService _service;
public ProductsController(
IProductService service)
{
_service = service;
}
[HttpGet]
public ActionResult GetProduct(int id)
{
var product = _service.GetById(id);
if (product == null)
return HttpNotFound();
return Json(product,
JsonRequestBehavior.AllowGet);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ProductDto dto)
{
if (!ModelState.IsValid)
return View(dto);
_service.Create(dto);
return RedirectToAction("Index");
}
}After (ASP.NET Core)
using Microsoft.AspNetCore.Mvc;
public class ProductsController : ControllerBase
{
private readonly IProductService _service;
public ProductsController(
IProductService service)
{
_service = service;
}
[HttpGet("{id}")]
public async Task<IActionResult> GetProduct(
int id)
{
var product = await _service
.GetByIdAsync(id);
if (product == null)
return NotFound();
return Ok(product);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(
ProductDto dto)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
await _service.CreateAsync(dto);
return RedirectToAction("Index");
}
}Automatyczne zmiany przez NetLift:
- •
System.Web.Mvc→Microsoft.AspNetCore.Mvc - •
Controller→ControllerBase(API controller) - •
ActionResult→IActionResult+ async/await - •
HttpNotFound()→NotFound() - •
Json(data, JsonRequestBehavior.AllowGet)→Ok(data) - • Service methods → async versions (
GetByIdAsync) - • Route attributes dla RESTful design
04Prawdziwe migracje do przejrzenia
Przepuściłem NetLift przez trzy znane open-source aplikacje .NET. Poniżej linki do PR-ów - możesz przejrzeć co dokładnie zostało zmienione.
ContosoUniversity - MVC 5 + EF6
Microsoft's official sample app for learning MVC and Entity Framework. 18 controllers, 45 views, complete CRUD operations, complex EF queries.
MvcMusicStore - E-commerce Sample
Classic ASP.NET MVC e-commerce application. Shopping cart, payment processing, admin panel. Real-world complexity with auth, validation, business logic.
eShopModernizing - Enterprise Patterns
Microsoft's modernization reference. WCF services, CQRS/MediatR patterns, complex domain logic. Representative of real enterprise applications.
Pro Tip: Warto przejrzeć te PR-y przed użyciem NetLift na swoim projekcie. Tab "Files changed" pokazuje side-by-side diff - najlepszy sposób żeby zobaczyć co narzędzie faktycznie robi.
05Scoring pewności transformacji
Nie każda transformacja jest tak samo pewna. Prosty namespace update to jedno, złożona logika biznesowa to drugie. NetLift przypisuje każdej transformacji confidence score.
| Confidence Level | Co to znaczy | Akcja wymagana | Przykłady |
|---|---|---|---|
| HIGH (95%+) | Transformacja deterministyczna, pokryta testami, mechaniczna zmiana | Minimal review, zaakceptuj zmiany | Using statements, namespace changes, attribute renames |
| MEDIUM (70-95%) | Transformacja strukturalna, może wymagać drobnych adjustments | Quick review, sprawdź edge cases | Controller methods, EF queries, return types |
| LOW (50-70%) | Częściowa transformacja, context-dependent changes | Detailed review, verify logic | WCF bindings, custom filters, complex LINQ |
| MANUAL | NetLift nie może zautomatyzować, wymaga ręcznej pracy | NetLift dodaje TODO comment z guidance | Custom auth, HttpContext manipulation, legacy patterns |
Przykład: TODO Comments dla Manual Work
Kiedy NetLift napotka kod, którego nie potrafi bezpiecznie zmigrować, dodaje komentarz z guidance:
// TODO: NetLift - Manual migration required
// REASON: Custom HttpContext manipulation detected
// GUIDANCE: Replace Session with IDistributedCache or ISession
// BEFORE:
// HttpContext.Session["UserId"] = userId;
// AFTER:
// await HttpContext.Session.SetStringAsync("UserId", userId);
// REFERENCE: https://learn.microsoft.com/aspnet/core/fundamentals/app-state
public class UserController : ControllerBase
{
public IActionResult Login(LoginDto dto)
{
// Your manual work here
}
}Lepsze niż cicha awaria. Wiesz co trzeba zrobić i masz link do dokumentacji.
06Ograniczenia
NetLift nie jest uniwersalnym rozwiązaniem. Obsługuje migrację aplikacji ASP.NET MVC/Web API z Entity Framework. Inne technologie .NET Framework wymagają innego podejścia.
NIE obsługiwane: WebForms
ASP.NET WebForms to kompletnie inna architektura (server-side events, ViewState, Page lifecycle). Nie ma prostej ścieżki migracji do ASP.NET Core. Opcje: przepisać do Blazor Server, utrzymać na .NET Framework, lub rebuild jako SPA.
Microsoft recommendation: Blazor migration path
NIE obsługiwane: WPF / WinForms
Desktop aplikacje mogą działać na .NET 8+ (Windows only), ale NetLift nie transformuje desktop-specific code. Większość WPF/WinForms apps działa bez zmian po zmianie target framework.
Szczegółowy przewodnik: Modernizacja WPF 2025
Częściowe wsparcie: Custom Authentication
Jeśli używasz custom auth providers, OWIN middleware, lub legacy identity systems, NetLift może zmigrować basic structures ale wymaga ręcznej weryfikacji. ASP.NET Core Identity jest fundamentalnie inne od Membership provider.
Częściowe wsparcie: Razor Views
NetLift migruje podstawowe Razor syntax, ale complex views z custom helpers, HtmlHelper extensions, lub legacy bundling wymagają ręcznej pracy. Tag Helpers w ASP.NET Core są bardziej powerful ale incompatible.
Jak sprawdzić compatibility przed rozpoczęciem?
NetLift ma built-in compatibility checker. Uruchom go przed migracją, żeby zobaczyć co jest supportowane:
dotnet netlift analyze --project ./MyApp.csproj --report compatibility
# Output:
# ✓ ASP.NET MVC Controllers: 45 found, 42 compatible (93%)
# ✓ Entity Framework 6 DbContext: 8 found, 7 compatible (87%)
# ⚠ WCF Services: 12 found, 9 compatible (75%)
# ✗ WebForms Pages: 23 found, NOT SUPPORTED
#
# Overall Compatibility Score: 78% (GOOD)
# Estimated Manual Work: 15-25% of total migration07Jak zacząć
NetLift jest narzędziem CLI. Instalujesz jako .NET global tool i uruchamiasz na swoim projekcie. Proces jest designed do być bezpieczny - najpierw dry run, potem transformacja, zawsze z backup.
Quick Start (5 minut)
1. Instalacja
dotnet tool install --global NetLiftWymaga .NET 8 SDK lub nowszego. NetLift sam jest written w .NET 8.
2. Compatibility Check
netlift analyze --project ./YourApp.csproj --report compatibilitySprawdzi co może być zmigrowane i wygeneruje raport. Zajmuje 30-60 sekund dla typical app.
3. Dry Run
netlift migrate --project ./YourApp.csproj --dry-run --output ./previewGeneruje preview zmian bez modyfikowania oryginalnych plików. Review w folderze ./preview.
4. Transformacja
# Backup first!
git commit -am "Pre-migration snapshot"
# Run migration
netlift migrate --project ./YourApp.csproj --backup ./backup
# NetLift creates backup automatically, but git commit is saferTransformuje pliki in-place. Zawsze backupuj przed rozpoczęciem.
5. Review & Test
# Review all TODO comments
grep -r "TODO: NetLift" ./src
# Build and test
dotnet build
dotnet test
# Review confidence scores
netlift report --project ./YourApp.csproj --format htmlNie ufaj blindly. Review zmian, szczególnie LOW confidence transformations.
⚡ Quick Facts
- →1819 test cases pokrywających wszystkie transformacje
- →AGPL-3.0 / Commercial - open source, licencja komercyjna dostępna
- →Cross-platform - działa na Windows, Linux, macOS
📖 Dokumentacja & Wsparcie
- →Full docs: GitHub Wiki
- →Issues & bugs: GitHub Issues
- →Examples: Sample migrations
- →Commercial help: Contact me
💼 Potrzebujesz Pomocy z Migracją Enterprise?
Enterprise migrations mają dodatkowe wymagania. Oferuję wsparcie komercyjne:
- • Custom transformation rules dla twojego codebase
- • Training sessions dla twojego zespołu
- • Review i optimization zmigrowanego kodu
- • Integration z twoim CI/CD pipeline
- • SLA support dla production migrations
08FAQ
Co to jest NetLift?
NetLift to open-source narzędzie oparte na Roslyn, które automatyzuje migrację z .NET Framework do .NET 8+. Przeprowadza deterministyczne transformacje kodu źródłowego: migruje kontrolery MVC 5 do ASP.NET Core, konwertuje zapytania Entity Framework 6 do EF Core, transformuje kontrakty WCF do gRPC, modernizuje wzorce CQRS. W przeciwieństwie do narzędzi AI, NetLift korzysta z drzew składniowych Roslyn do precyzyjnych transformacji bez losowości. Każda transformacja jest pokryta testami (1819 test cases).
Czym NetLift różni się od .NET Upgrade Assistant?
.NET Upgrade Assistant migruje pliki projektów (.csproj), ale nie dotyka kodu źródłowego. NetLift robi odwrotnie - transformuje sam kod (kontrolery, zapytania bazodanowe, kontrakty API), podczas gdy Upgrade Assistant aktualizuje strukturę projektu. W praktyce oba narzędzia się uzupełniają: Upgrade Assistant do plików projektu, NetLift do kodu. Kluczowa różnica: Upgrade Assistant wymaga ręcznej pracy nad kodem (często 60-80% czasu migracji), NetLift automatyzuje właśnie tę mechaniczną pracę.
Czy NetLift korzysta ze sztucznej inteligencji?
Nie. NetLift używa Roslyn (kompilatora C#) do analizy drzew składniowych i deterministycznych transformacji. Żadnych LLM, żadnych modeli językowych, żadnej losowości. Każda transformacja jest oparta na regułach i pokryta testami. To design decision: migracja kodu musi być przewidywalna i powtarzalna. AI może generować niespójny kod lub wprowadzać subtelne błędy. Roslyn daje gwarancję: ta sama transformacja zawsze produkuje ten sam wynik.
Jakie aplikacje .NET może migrować NetLift?
NetLift obsługuje: ASP.NET MVC 5 aplikacje, Entity Framework 6 data access, WCF services (migracja do gRPC), CQRS/MediatR patterns, klasyczne API controllers. Najlepiej sprawdza się przy aplikacjach biznesowych: e-commerce, enterprise apps, SaaS platformy. Nie obsługuje: WebForms (zbyt różne od modern web), WPF/WinForms desktop apps (pozostają na .NET Framework lub wymagają przepisania). Sprawdź compatibility checking command przed rozpoczęciem migracji.
Czy NetLift jest darmowy?
NetLift jest dual-licensed. AGPL-3.0 dla projektów open source, licencja komercyjna dla zastosowań proprietary. Kod jest dostępny na GitHub: github.com/wojciechowskiapp/NetLift. To jest community project - zgłaszaj bugi, proponuj features, contribut'uj pull requesty. Jeśli potrzebujesz wsparcia komercyjnego, szkoleń lub pomocy przy złożonej migracji enterprise, skontaktuj się ze mną.
Najważniejsze Wnioski
- →NetLift automatyzuje mechaniczną pracę przy migracji .NET Framework do .NET 8+
- →Oparte na Roslyn - deterministyczne transformacje, bez AI
- →Migruje MVC 5, EF6, WCF, CQRS z confidence scoring na każdej transformacji
- →Dual license: AGPL-3.0 dla open source, komercyjna dla proprietary. 1819 testów
- →Nie obsługuje WebForms, WPF, WinForms. Zawsze review przed deployment
Wypróbuj NetLift na GitHub
NetLift jest w pełni open-source. Zainstaluj jako .NET global tool i wypróbuj na swoim projekcie. Jeśli masz pytania, bugi do zgłoszenia, albo potrzebujesz pomocy z enterprise migration - daj znać.
Powiązane Artykuły
Przewodnik Migracji .NET
Kompletna strategia migracji z .NET Framework 4.8 do .NET 10
Modernizacja Systemów Legacy
Framework decyzyjny i strategie modernizacji aplikacji legacy
Modernizacja WPF 2025
Migrować, opakować czy przebudować? Decision framework dla desktop apps
Kalkulator Kosztów Modernizacji
Framework obliczania ROI i kosztów modernizacji systemów legacy
Źródła
- [1] .NET Upgrade Assistant - Microsoft -https://dotnet.microsoft.com/platform/upgrade-assistant
- [2] Roslyn Compiler Platform - GitHub -https://github.com/dotnet/roslyn
- [3] NetLift Open Source Project -https://github.com/wojciechowskiapp/NetLift
- [4] ASP.NET Core Migration Documentation -https://learn.microsoft.com/aspnet/core/migration/mvc
- [5] Entity Framework Core Migration Guide -https://learn.microsoft.com/ef/core/what-is-new/ef-core-8.0/whatsnew
- [6] WCF to gRPC Migration -https://learn.microsoft.com/dotnet/architecture/grpc-for-wcf-developers/
- [7] MediatR Documentation -https://github.com/jbogard/MediatR
- [8] ContosoUniversity Sample Application -https://github.com/dotnet/AspNetCore.Docs
- [9] .NET 8 Performance Improvements -https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/
- [10] Roslyn Syntax Trees and Semantic Model -https://learn.microsoft.com/dotnet/csharp/roslyn-sdk/