## Wstęp merytoryczny: Ewolucja od .NET 4.8 do ASP.NET Core i Blazor w .NET 10 Przejście ze środowiska desktopowego, opartego o **.NET Framework 4.8** (WinForms, WPF), do nowoczesnego ekosystemu **ASP.NET Core** i frameworka **Blazor** reprezentuje fundamentalną zmianę paradygmatu architektonicznego. Ekosystem .NET ewoluował z platformy zamkniętej w systemie Windows (zależnej od ciężkiego API systemu operacyjnego) do wydajnego, wieloplatformowego rozwiązania open-source. ASP.NET Core wprowadza koncepcję zwinnego, modularnego potoku żądań HTTP obsługiwanego przez serwer **Kestrel**, podczas gdy Blazor pozwala na tworzenie interfejsów użytkownika bezpośrednio w języku C#, eliminując historyczną konieczność dzielenia logiki pomiędzy C# a JavaScript. Transformacja z tradycyjnego oprogramowania typu "gruby klient" (Stateful) na środowisko webowe w .NET 10 wymaga zrozumienia mechanizmów asynchroniczności, nowoczesnego wstrzykiwania zależności (DI) oraz odmiennego cyklu życia aplikacji. ## Analiza Porównawcza: Desktop vs Nowoczesny Web (.NET 10) Wiedza zdobyta przy tworzeniu aplikacji WPF i WinForms stanowi solidny fundament, jednak wymaga mapowania na wzorce używane w aplikacjach ASP.NET Core i komponentach Blazor: | **Koncepcja Desktop (WPF/WinForms)** | **Odpowiednik w .NET 10 (ASP.NET Core / Blazor)** | **Charakter zmiany architektonicznej** | | ----------------------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Window / UserControl** | **Komponent Razor (.razor)** | Przejście z XAML/projektanta WinForms na deklaratywny, oparty na C# i HTML komponent UI działający w przeglądarce lub na serwerze. | | **App.config / Web.config** | **appsettings.json** | Rezygnacja ze statycznego, ciężkiego pliku XML na rzecz hierarchicznego pliku JSON, z wbudowanym wsparciem wstrzykiwania zależności i konfiguracji środowiskowej. | | **Zdarzenia UI (Click, Loaded)** | **EventCallback / OnInitializedAsync** | Zdarzenia systemowe i cykl życia stają się w pełni asynchroniczne i zintegrowane z cyklem renderowania frameworka Blazor. | | **Globalne instancje (Static/Singleton)** | **Dependency Injection (Wbudowany kontener DI)** | Stan w ASP.NET Core jest zarządzany poprzez usługi o ściśle określonym cyklu życia (Transient, Scoped, Singleton) rejestrowane w klasie bazowej. | | **Stan w pamięci RAM aplikacji** | **Obwód (Circuit) / Stateless API** | Przejście z grubego klienta przechowującego dane lokalnie, na stan rozproszony lub utrzymywany na serwerze za pomocą połączenia SignalR w modelu Blazor Server. | ## Mechanika potoku ASP.NET Core i Modele Blazor ### Hosting i Middleware Tradycyjna architektura .NET 4.8 często opierała się na potężnej i zmonolityzowanej bibliotece `System.Windows`. W nowoczesnym ASP.NET Core sercem aplikacji jest **Generic Host** oraz modularny rurociąg żądań HTTP (Request Pipeline) ułożony z komponentów **Middleware**. Żądanie przechodzi przez kolejne filtry, w których każde oprogramowanie pośredniczące może zmodyfikować kontekst, zanim zostanie przekazane do odpowiedniego sterownika lub komponentu renderującego. ### Modele uruchomieniowe Blazor Blazor nie jest pojedynczą technologią, ale modelem komponentowym, który można osadzić w różnych konfiguracjach hostingowych: * **Blazor Server:** Komponenty wykonywane są po stronie serwera wewnątrz aplikacji ASP.NET Core. Komunikacja UI odbywa się poprzez protokół WebSockets z użyciem SignalR. Stan powiązany z połączonym klientem nazywany jest "obwodem" (circuit). Pozwala to na pełny dostęp do zasobów serwera bez wysyłania kodu C# do przeglądarki. * **Blazor WebAssembly (Wasm):** Aplikacja (wraz z runtime'em .NET) pobierana jest do przeglądarki klienta i wykonywana w piaskownicy przeglądarki (sandbox). Model ten umożliwia pełną pracę w trybie offline, w architekturze PWA (Progressive Web App) i zdejmuje obciążenie obliczeniowe z serwera. * **Blazor Hybrid:** Łączy nowoczesne technologie webowe z oprogramowaniem natywnym. ## Dobre Praktyki i Antywzorce W procesie przenoszenia logiki z .NET Framework 4.8 do architektury .NET 10 łatwo popełnić błędy polegające na przenoszeniu dawnych nawyków w nowe ramy technologiczne. * **Antywzorzec (ZASADA ZERO HYBRYDY W 4.8):** Choć w oficjalnej dokumentacji pojawiają się informacje o integracji kontrolek `BlazorWebView` w celu modernizacji istniejących aplikacji WPF czy Windows Forms, należy to kategorycznie sprostować w odniesieniu do środowisk współdzielonych z .NET 4.8. Użycie natywnego Blazora w "starej" aplikacji Windows Forms w architekturze Framework 4.8 jest niemożliwe; mechanika hybrydowa z `BlazorWebView` wymaga zastosowania nowoczesnego środowiska uruchomieniowego w projektach natywnych .NET 6+. Migracja musi polegać na wydzieleniu logiki biznesowej do .NET Standard 2.0 i sukcesywnym podpinaniu nowoczesnego front-endu w architekturze .NET 10. * **Antywzorzec:** Blokowanie wątków systemowych (np. `Thread.Sleep` czy synchroniczne `Wait()` na zadaniach). Aplikacje ASP.NET Core i serwer Kestrel zostały zoptymalizowane pod kątem tysięcy współbieżnych połączeń dzięki zastosowaniu mechanizmów asynchronicznych. Złamanie tej zasady w architekturze webowej zdestabilizuje serwer. Programowanie musi być w całości oparte o wzorce `async/await`. * **Dobra praktyka:** Pełna separacja logiki prezentacji (Blazor/API) od logiki biznesowej i dostępu do danych (Entity Framework Core) za sprawą Dependency Injection. W ASP.NET Core wstrzykiwanie zależności nie jest zewnętrznym dodatkiem – to wbudowany filar frameworka udostępniany poprzez interfejs `WebApplicationBuilder.Services`. Umożliwia to zjawisko całkowicie luźnego powiązania (loose coupling) i oddzielenie kodu renderującego UI od operacji I/O. ## Laboratorium kodu: Rejestracja usług i budowa komponentu Poniżej przedstawiono implementację ilustrującą współdziałanie nowej mechaniki konfiguracyjnej oraz architektury asynchronicznej. Rejestracja zależności odbywa się w pliku punktu startowego `Program.cs`, co zastępuje w całości dawne konstrukcje z wykorzystaniem `Global.asax` i ciężkich konstruktorów. ```csharp // Program.cs w .NET 10 (Uproszczony model Generic Host) using Microsoft.EntityFrameworkCore; using ModernApp.Data; var builder = WebApplication.CreateBuilder(args); // Rejestracja puli logiki poprzez wbudowany kontener DI builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); // Użycie appsettings.json do odczytu Connection Stringa wstrzykiwanego do EF Core builder.Services.AddDbContextFactory(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); var app = builder.Build(); // Konfiguracja potoku żądań Middleware if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAntiforgery(); app.MapRazorComponents() .AddInteractiveServerRenderMode(); app.Run(); ``` Mechanika po stronie klienta również ulega uproszczeniu, przechodząc z obiektów `Dispatcher` na zautomatyzowany cykl odświeżania cyklu życia. Poniżej przedstawiony jest w pełni asynchroniczny komponent odczytujący dane z systemu, respektujący zasady modelu bezstanowego po stronie UI: ```csharp // TasksList.razor @page "/tasks" @inject ITaskService TaskService
@if (_tasks == null) {

Ładowanie strumieniowe, proszę czekać...

} else { @foreach (var task in _tasks) { }
@task.Title @task.AssignedTo
}
@code { private List? _tasks; // Asynchroniczny odpowiednik zdarzenia Form_Load / UserControl.Loaded protected override async Task OnInitializedAsync() { // Wywołanie usługi wstrzykniętej z DI - brak blokowania wątku interfejsu (UI Thread) _tasks = await TaskService.GetActiveTasksAsync(); } } ``` ## Wnioski architektoniczne Porzucenie zmonolityzowanego modelu *Stateful* (aplikacji stanowych Desktop w .NET 4.8) na rzecz ekosystemu **.NET 10**, gdzie dominuje bezstanowa architektura potoku żądań (Middleware) i elastyczne hostowanie interfejsu (Blazor Server/WebAssembly), wymaga transformacji sposobu projektowania pamięci i stanu aplikacji. Blazor upodabnia pisanie nowoczesnego, responsywnego interfejsu klienta do modelu podobnego pod względem mentalnym do wzorca znanej abstrakcji klas c#, jednak eliminuje bezpośredni, procesowy dostęp do hardware’u stacji roboczej z poziomu interfejsu, wymuszając w pełni asynchroniczną i bezpieczną integrację poprzez komunikację sieciową (API i potoki wstrzykiwania zależności).