ASP.NET Core 9 kontynuuje kierunek obranego wcześniej rozwoju, integrując różne podejścia do tworzenia interfejsów użytkownika w aplikacjach webowych – od tradycyjnego renderowania po stronie serwera z użyciem Razor Pages i MVC, aż po nowoczesne, interaktywne interfejsy oparte na Blazorze. Każde z tych podejść odpowiada innym potrzebom architektonicznym i operacyjnym, ale wszystkie dzielą wspólny fundament w postaci zunifikowanego środowiska ASP.NET Core.

Razor Pages reprezentują uproszczone podejście do tworzenia stron, w którym logika i widok są silnie ze sobą związane. Struktura oparta na konwencji — pliki .cshtml zawierające widok i kod zaplecza w formie klas PageModel — ułatwia szybkie wdrażanie funkcjonalności w sposób uporządkowany. Dzięki Razor Pages możliwe jest tworzenie aplikacji o wysokim stopniu spójności między warstwą prezentacji a logiką biznesową, co sprawia, że technologia ta sprawdza się w projektach, gdzie istotna jest przewidywalność zachowania kodu i prostota.

MVC, jako bardziej klasyczne podejście oparte na wzorcu Model-View-Controller, oferuje wyraźną separację odpowiedzialności. Kontrolery obsługują żądania HTTP, współpracują z modelem danych i decydują o tym, który widok powinien zostać wyrenderowany. W porównaniu z Razor Pages, MVC zapewnia większą elastyczność w organizacji kodu i jego testowalności. Jest odpowiedni dla aplikacji, które wymagają bardziej złożonego przetwarzania żądań lub silnej logiki aplikacyjnej rozdzielonej od warstwy prezentacji.

Blazor to natomiast technologiczna rewolucja w obrębie ekosystemu .NET, umożliwiająca tworzenie dynamicznych, bogatych interfejsów użytkownika działających bezpośrednio w przeglądarce. Blazor WebAssembly działa po stronie klienta, kompilując kod .NET do WebAssembly, co pozwala na wykonywanie logiki aplikacyjnej bez pośrednictwa serwera. Alternatywnie, Blazor Server utrzymuje stałe połączenie SignalR między klientem a serwerem, co zapewnia natychmiastowe odświeżanie interfejsu przy minimalnym zużyciu zasobów klienta. Blazor umożliwia inżynierom .NET tworzenie nowoczesnych aplikacji typu SPA (Single Page Application) bez konieczności uczenia się odrębnych technologii frontendowych jak Angular, React czy Vue.

Zaletą Blazora jest również jego pełna integracja z .NET – zarówno pod względem modeli danych, walidacji, jak i bezpieczeństwa. Komponenty w Blazorze są reużywalne, co zwiększa produktywność i pozwala na utrzymanie spójności interfejsu. Dodatkowo, Blazor wspiera interopercję z JavaScriptem, dzięki czemu nie ogranicza programisty wyłącznie do środowiska .NET – możliwa jest płynna współpraca z istniejącym kodem JS lub zewnętrznymi bibliotekami frontendowymi.

W praktyce, podejścia te można łączyć. Hybrydowe rozwiązania, w których część aplikacji jest renderowana po stronie serwera przy użyciu MVC lub Razor Pages, a wybrane fragmenty interfejsu działają w Blazorze, umożliwiają dostosowanie architektury aplikacji do konkretnych wymagań biznesowych i technologicznych. Takie podejście pozwala też na płynne przechodzenie z klasycznych technologii .NET do nowoczesnych modeli aplikacyjnych bez konieczności pełnej migracji.

Zrozumienie różnic pomiędzy Razor Pages, MVC i Blazorem, a także ich praktyczne zastosowanie w zależności od charakterystyki projektu, to klucz do budowy nowoczesnych, skalowalnych i responsywnych aplikacji webowych w ASP.NET Core 9. Integracja z JavaScriptem, możliwość pracy w trybie offline, pełne wsparcie dla routingu, dependency injection oraz silna typizacja czynią z ASP.NET Core 9 wszechstronne narzędzie do pracy zarówno dla doświadczonych architektów, jak i mniej zaawansowanych programistów poszukujących stabilnego fundamentu technologicznego.

Dla pełnego wykorzystania możliwości ASP.NET Core 9 w zakresie budowy interfejsów użytkownika, kluczowe jest zrozumienie wzorca komponentowego w Blazorze, sposobu zarządzania stanem aplikacji oraz komunikacji pomiędzy komponentami. Równie istotne pozostaje pojęcie renderowania warunkowego, dynamicznego ładowania danych oraz optymalizacji wydajności przy dużych strukturach DOM. W przypadku MVC – należy pogłębić znajomość atrybutów routingu, model bindingu i filtrów akcji, które umożliwiają finezyjną kontrolę nad przepływem żądań HTTP. Razor Pages z kolei wymaga świadomego stosowania mechanizmów takich jak TempData, ViewData czy model walidacji, by w pełni wykorzystać jego zalety przy zachowaniu czytelności kodu.

Jak wykorzystać EF Core i Dapper do efektywnej pracy z bazą danych?

Migracje w Entity Framework Core (EF Core) tworzą zestaw klas w projekcie, które nie powinny być zmieniane ręcznie. Jak pokazano na przykładzie, po uruchomieniu migracji, trzy pliki zostały dodane do folderu Migrations w aplikacji. Te pliki zawierają skrypty do tworzenia zasobów w bazie danych, jak na przykład tabeli "Customers". Dzięki migracjom możemy śledzić historię zmian w modelu domeny aplikacji i utrzymać bazę danych w zgodzie z wersją aplikacji.

Podczas każdej zmiany w modelu domeny aplikacji, należy dodać nową migrację. Dzięki temu mamy możliwość śledzenia zmian i łatwego zarządzania ewolucją bazy danych. Następnie, aby zaktualizować bazę danych, nie musimy ręcznie wykonywać żadnych skryptów SQL w SQL Server. Zamiast tego, korzystając z narzędzia wiersza poleceń (CLI) EF Core, możemy wykonać aktualizację bazy danych zgodnie z wersją mapowaną w aplikacji. Polecenie dotnet ef database update automatycznie wykona wszystkie skrypty potrzebne do stworzenia bazy danych i tabel, co pokazuje przykład utworzonych obiektów w bazie danych.

Kiedy baza danych jest już stworzona, czas na dodanie API umożliwiającego interakcję z bazą. W tym celu, w pliku Program.cs, definiujemy odpowiednie ścieżki, które umożliwiają pobieranie danych z tabeli "Customers", ich dodawanie lub edytowanie. Warto zwrócić uwagę na sposób, w jaki te metody działają – wszystkie operacje na bazie danych są obsługiwane przez dbContext, który zapewnia automatyczne mapowanie danych na odpowiednie obiekty w aplikacji, a także zarządza połączeniami i transakcjami. Dzięki temu kod pozostaje czysty i przejrzysty, a wszystkie operacje wykonywane są asynchronicznie, co zwiększa wydajność aplikacji.

Warto również zwrócić uwagę na rolę asynchronicznego przetwarzania i tokenów anulowania w nowoczesnym programowaniu webowym. Dzięki użyciu słów kluczowych async i await, aplikacja jest w stanie obsługiwać więcej żądań jednocześnie, nie blokując wątków podczas operacji takich jak zapytania do bazy danych czy dostęp do plików. Asynchroniczność nie tylko pozwala na lepszą skalowalność aplikacji, ale także zapewnia, że aplikacja pozostaje responsywna nawet przy dużym obciążeniu. Użycie tokenów anulowania umożliwia zarządzanie przerwaniem żądania i zwolnienie zasobów, co poprawia odporność aplikacji.

Korzystanie z ORM, takich jak EF Core, niesie ze sobą wiele zalet, ale także wyzwań, szczególnie w kontekście wydajności. Mimo że ORM-y ułatwiają pracę z danymi, mogą być mniej wydajne w porównaniu do tradycyjnych podejść do mapowania danych. W przypadku dużych aplikacji, które muszą przetwarzać ogromne ilości danych, można napotkać na ograniczenia związane z czasem odpowiedzi i użyciem zasobów. Z tego powodu warto rozważyć zastosowanie tzw. "Micro ORM", jak np. Dapper, który oferuje wysoką wydajność przy jednoczesnym zachowaniu elastyczności w mapowaniu danych.

Dapper to lekka biblioteka, która pozwala na efektywną interakcję z bazą danych, oferując mapowanie wyników zapytań do obiektów C#. Choć Dapper i EF Core są dwiema różnymi technologiami, mogą być stosowane razem w jednym projekcie, co daje korzyści w postaci lepszej wydajności, szczególnie przy skomplikowanych zapytaniach. Aby dodać Dapper do projektu, wystarczy zainstalować odpowiednią paczkę za pomocą polecenia dotnet add package Dapper. Dapper jest łatwy w użyciu i daje dużą swobodę przy projektowaniu zapytań.

Po zainstalowaniu Dappera, można wprowadzić dwie nowe ścieżki w pliku Program.cs, które umożliwiają wykonywanie zapytań do bazy danych z użyciem Dappera. Dzięki tej bibliotece, możemy szybko i wydajnie pobierać dane z bazy, takie jak lista wszystkich klientów, bez potrzeby używania ciężkiego ORM-a, co może być szczególnie przydatne w przypadku prostych zapytań, które nie wymagają pełnej struktury zarządzania danymi jak w EF Core.

Różnice między podejściami ORM i Micro ORM są wyraźne, i warto zdawać sobie sprawę z tego, kiedy warto sięgnąć po jedno lub drugie narzędzie. Choć ORM, jak EF Core, zapewnia bogate funkcje, takie jak śledzenie zmian w modelu i automatyczne mapowanie obiektów na tabele, jego użycie może być czasami nieoptymalne w kwestii wydajności. Dapper, z drugiej strony, to bardziej bezpośrednie podejście do pracy z danymi, które nie oferuje pełnej integracji z modelem aplikacji, ale za to pozwala na szybkie i wydajne zapytania w sytuacjach, gdy zależy nam na jak najlepszej wydajności.

W praktyce, użycie EF Core i Dapper razem może być bardzo skuteczne. EF Core sprawdza się świetnie w bardziej złożonych operacjach, gdzie potrzebujemy pełnej obsługi modelu danych i migracji bazy, podczas gdy Dapper może być używany do prostych zapytań i operacji, które muszą działać szybko i efektywnie.

Jak przygotować i opublikować aplikację ASP.NET Core 9 przy użyciu narzędzia CLI .NET?

Proces przygotowania i publikacji aplikacji ASP.NET Core 9 opiera się na generowaniu pakietów publikacyjnych, które zawierają niezbędne pliki do uruchomienia aplikacji w różnych środowiskach – lokalnych oraz chmurowych. Kluczowym narzędziem do tego celu jest interfejs wiersza poleceń (CLI) platformy .NET, który umożliwia skompilowanie i spakowanie projektu do formatu gotowego do wdrożenia.

Polecenie dotnet publish jest fundamentem tego procesu i oferuje szereg opcji konfiguracyjnych, które pozwalają precyzyjnie dostosować wynikowy pakiet publikacyjny. Najczęściej wykorzystywane parametry to: określenie konfiguracji kompilacji (-c), ścieżki wyjściowej dla plików publikacji (-o), oraz wyłączenie ponownego przywracania zależności (--no-restore), co bywa przydatne w procesach CI/CD. Konfiguracja Debug jest dedykowana testom i diagnostyce, zawiera informacje pomocne przy debugowaniu, podczas gdy Release optymalizuje aplikację pod kątem wydajności, pozbawiając jej dodatkowych danych debugowych, co jest preferowane w środowiskach produkcyjnych.

Struktura wygenerowanego katalogu publikacji odzwierciedla wszystkie komponenty niezbędne do działania aplikacji: pliki konfiguracyjne (appsettings.json i jego warianty), pliki statyczne umieszczone w folderze wwwroot (takie jak CSS, JavaScript czy obrazy), oraz bibliotek dynamicznie ładowane (.dll) wraz z samym plikiem wykonywalnym aplikacji. Warto podkreślić, że to właśnie zawartość tego katalogu powinna zostać przeniesiona do środowiska docelowego, niezależnie czy jest to lokalny serwer, czy usługa chmurowa.

Uruchamianie aplikacji odbywa się poprzez wykonanie polecenia dotnet NazwaAplikacji.dll. Wymaga to zainstalowanego na docelowej maszynie .NET Runtime — środowiska wykonawczego odpowiedzialnego za uruchamianie aplikacji, zarządzanie pamięcią oraz obsługę wyjątków. Runtime różni się od SDK tym, że nie zawiera narzędzi developerskich, a jedynie komponenty niezbędne do działania gotowych programów. Ta rozdzielność pozwala na lżejszą instalację środowiska na serwerach produkcyjnych.

Platforma .NET Core, w tym ASP.NET Core 9, jest w pełni przenośna i może być uruchamiana na różnych systemach operacyjnych — Linux, macOS i Windows — pod warunkiem zainstalowania odpowiedniego SDK lub Runtime. Popularne serwery aplikacji i webserwery, takie jak Kestrel, Nginx, Apache, IIS czy HTTP.sys, wspierają hostowanie aplikacji ASP.NET Core, co umożliwia elastyczne dostosowanie infrastruktury do wymagań projektu.

Proces publikacji aplikacji przy pomocy CLI jest na tyle prosty, że może zostać w pełni zautomatyzowany, co stanowi podstawę nowoczesnego podejścia DevOps i ciągłej integracji (CI/CD). Automatyzacja zapewnia powtarzalność, bezpieczeństwo i szybsze dostarczanie oprogramowania.

W kontekście wdrożeń chmurowych, przygotowanie właściwego pakietu publikacyjnego jest kluczowym etapem. Po stronie chmury następuje już jedynie uruchomienie aplikacji w oparciu o dostarczone pliki, co znacząco upraszcza cały proces i umożliwia szybkie skalowanie usług.

Ważne jest, aby rozumieć, że pakiet publikacyjny zawiera wszystkie zależności, zarówno te własne aplikacji, jak i zewnętrzne biblioteki, co eliminuje konieczność instalowania dodatkowych komponentów na serwerze poza samym .NET Runtime. Dzięki temu wdrożenie jest niezależne od środowiska developerskiego i eliminuje potencjalne niespójności.

Ponadto, kluczowe znaczenie ma świadomość różnic między środowiskami programistycznymi i produkcyjnymi. Konfiguracja Debug jest narzędziem do tworzenia i testowania, ale nigdy nie powinna być używana w produkcji ze względu na obciążenie i potencjalne ryzyko ujawnienia wewnętrznych informacji aplikacji. Konfiguracja Release stanowi z kolei standard do publikacji i powinna być jedyną wykorzystywaną przy wdrożeniach produkcyjnych.

Z punktu widzenia zarządzania projektem i operacji IT, znajomość struktury plików w katalogu publikacji oraz sposobu działania narzędzia dotnet publish jest nieodzowna do efektywnego przygotowania aplikacji do wdrożenia i dalszego utrzymania. Rozumienie mechanizmów działania platformy i narzędzi umożliwia także efektywną diagnostykę problemów pojawiających się podczas wdrożeń.