V moderním vývoji softwaru je často nezbytné načítat a vykonávat kód dynamicky za běhu aplikace. Tento přístup nabízí velkou flexibilitu, umožňuje načítat a spouštět funkce nebo třídy, které nebyly známé v době kompilace. Taková technika je velmi užitečná například pro vytváření pluginových systémů nebo aplikací, které musí reagovat na různé požadavky uživatelů bez nutnosti opětovné kompilace. Tento proces může výrazně zlepšit efektivitu správy paměti a umožnit lepší využití zdrojů.
V následujícím textu se podíváme na praktické příklady, jak dynamicky načítat knihovny a provádět metody během běhu aplikace v .NET. Začneme s jednoduchým příkladem, kde upravíme kód tak, aby využíval zastaralé metody a následně je nahrazoval novějšími variantami.
Prvním krokem je vytvoření metody, která označí starou metodu jako zastaralou. V souboru Animal.cs přidáme metodu Speak(), která bude označena atributem Obsolete. Tento atribut upozorňuje na to, že metoda je zastaralá a místo ní by se měla použít nová metoda, například SpeakBetter():
Následně je nutné upravit kód v souboru Program.cs, aby dynamicky detekoval zastaralé metody a výstupem je informace o tom, která metoda byla označena jako zastaralá. Můžeme použít následující kód, který prochází všechny metody a vrací, zda jsou označeny jako zastaralé:
Po spuštění programu bude výstup obsahovat informace o metodě Speak(), která bude označena jako zastaralá s uvedením, jak ji nahradit novější metodou SpeakBetter().
Další zajímavou technikou v .NET je dynamické načítání sestav během běhu aplikace. Tento přístup je zvláště užitečný, pokud nevíte, které knihovny budete potřebovat, dokud aplikace není spuštěna. Můžeme mít například aplikaci, která nemusí mít vždy načtené všechny funkce, ale na základě potřeb uživatele může aktivovat konkrétní funkce (například funkci pro hromadnou korespondenci v textovém editoru).
Představme si, že máme projekt DynamicLoadAndExecute.Library, který obsahuje třídu Dog se metodou Speak(). Tato třída bude dynamicky načítána a její metody volány až během běhu aplikace.
Postupujeme podle následujících kroků:
-
Vytvoříme nový projekt DynamicLoadAndExecute.Library a v něm definujeme třídu Dog:
-
Vytvoříme nový konzolový projekt DynamicLoadAndExecute.Console, který bude načítat knihovnu z prvního projektu a spouštět její metody.
-
Po vytvoření obou projektů přeneseme potřebné soubory z knihovny do konzolového projektu. Poté definujeme metodu pro výstup informací o načtené sestavě a jejích typech:
-
Vytvoříme třídu DemoAssemblyLoadContext, která bude zodpovědná za načítání sestav do paměti:
-
V souboru Program.cs použijeme tento kontext k dynamickému načítání sestavy a instanciování třídy Dog:
Tento postup umožňuje dynamické načítání knihoven a jejich metod za běhu aplikace. Výhoda tohoto přístupu spočívá nejen ve flexibilitě a efektivitě, ale také v optimalizaci využití paměti, protože knihovny lze načítat pouze v případě potřeby a po jejich použití je lze z paměti uvolnit.
Důležité aspekty k pochopení:
-
Dynamické načítání sestav je užitečné pro aplikace, které potřebují pracovat s různými moduly nebo pluginy, které nejsou známé předem.
-
Použití reflexe pro invokaci metod může mít výkonnostní náklady, ale moderní verze .NET, jako .NET 7, tento proces výrazně optimalizují.
-
Správa paměti při dynamickém načítání sestav je také klíčová, protože nesprávné uvolnění zdrojů může vést k únikům paměti. Proto je důležité používat AssemblyLoadContext pro správné uvolnění knihoven po jejich použití.
Jak implementovat rate limiting a autentifikaci v .NET Web API
V moderních webových aplikacích je správné řízení přístupu a ochrana před přetížením klíčovými aspekty, které zajišťují stabilitu a bezpečnost. Mezi efektivní techniky, jak tyto problémy řešit, patří omezení počtu požadavků (rate limiting) a autentifikace pomocí tokenů. V této kapitole se zaměříme na to, jak implementovat tyto mechanismy v aplikaci založené na .NET Web API.
Rate limiting je technika, která omezuje počet požadavků, které mohou být provedeny během určitého časového okna. Tento mechanismus je nezbytný pro ochranu aplikace před zneužitím, například při masovém odesílání požadavků nebo při útocích typu DoS (Denial of Service). V .NET aplikacích lze rate limiting implementovat jednoduše díky vestavěné podpoře, která byla představena v ASP.NET Core.
Pro implementaci rate limiting v projektu Web API začneme importováním potřebných knihoven, jak ukazuje následující kód:
Dále nastavíme proměnnou, která bude určovat, zda chceme používat tuto vestavěnou funkci:
V následujícím kroku je třeba nakonfigurovat endpoint pro získávání produktů. Tento endpoint bude omezen pravidlem, které povolí maximálně 5 požadavků za každých 10 sekund:
Na konci souboru Program.cs musíme přidat konfiguraci pro rate limiting, kde definujeme konkrétní pravidlo omezující počet požadavků:
Po úspěšném nastavení rate limiting můžete testovat aplikaci. V konzolovém klientovi budou požadavky podléhat těmto limitům. Například, pokud uživatel provede více než 5 požadavků za 10 sekund, aplikace pozastaví požadavky, dokud nevyprší časové okno.
Další důležitou součástí bezpečnosti webových služeb je autentifikace a autorizace. V tomto případě je jedním z nejběžnějších způsobů autentifikace použití JWT (JSON Web Token). JWT je standard pro bezpečnou výměnu informací mezi stranami ve formátu JSON. Tento token je podepsán, což zaručuje jeho pravost. Autentifikace pomocí JWT je často používána pro ověřování identity uživatelů při přístupu k chráněným API.
V rámci vývoje aplikace musíme přidat podporu pro JWT autentifikaci. Nejprve je nutné importovat příslušný namespace pro práci s bezpečnostními nároky:
Pak přidáme potřebné služby pro autentifikaci a autorizaci v souboru Program.cs:
Na závěr je třeba zajistit, že aplikace bude používat autentifikaci a autorizaci při každém požadavku:
Díky těmto nastavením může webová aplikace ověřovat požadavky na základě JWT tokenů, které jsou připojeny k požadavkům uživatelů. Tokeny jsou generovány po úspěšné autentifikaci uživatele a slouží k ověření jeho identity při každém dalším přístupu k chráněným zdrojům.
Přístup k citlivým datům by měl být vždy chráněn odpovídajícími bezpečnostními mechanismy. Ačkoli rate limiting a autentifikace pomocí JWT představují základní bezpečnostní vrstvy, je důležité nezapomínat na další kroky, jako je validace vstupů, šifrování dat v průběhu přenosu (například pomocí HTTPS) a pravidelné aktualizace softwaru. Celkově jde o to, aby aplikace byla schopná efektivně řídit přístup a chránit se před zneužitím.
Jak efektivně využít OData pro webové aplikace v prostředí ASP.NET MVC
Vytváření webových aplikací s využitím OData poskytuje efektivní způsob, jak zpřístupnit data pro různé klienty. Tento proces se neomezuje pouze na jednoduchý přístup k datům, ale umožňuje také jejich filtrování, třídění a rozšiřování o další související informace. V této části se zaměříme na integraci OData do MVC aplikace pomocí konkrétního příkladu práce s daty o produktech.
Začneme tím, že ve Visual Studio Code vybereme projekt Northwind.OData.Client.Mvc jako aktivní projekt OmniSharp. Následně přidáme referenci na projekt Northwind.Common.EntityModels.SqlServer, který je umístěn ve složce Chapter02. Po sestavení tohoto projektu otevřeme soubor launchSettings.json ve složce Properties a upravíme port pro HTTPS na 5102 tak, jak je uvedeno v následujícím kódu:
Dále v projektu Northwind.OData.Client.Mvc ve složce Models vytvoříme novou třídu ODataProducts.cs, která bude definovat strukturu pro produkty vrácené službou OData. Tato třída bude obsahovat pole Value, které bude polem objektů typu Product:
V souboru Program.cs přidáme kód pro nastavení typu médií v HTTP hlavičce:
Následně registrujeme HTTP klienta pro službu OData, který bude používat formát JSON pro odpověď:
Nyní přistoupíme k volání služby OData na domovské stránce aplikace. V souboru HomeController.cs deklarujeme pole pro uchování zaregistrované HTTP klientské služby. Dále v konstruktoru třídy přidáme kód pro její předání a uložení:
Metodu Index učiníme asynchronní a přidáme kód pro volání služby OData, která vrací produkty začínající písmeny "Cha". Výsledek uložíme do slovníku ViewData, aby ho bylo možné zobrazit v pohledu:
Na straně zobrazení (Index.cshtml) odstraníme původní markup a přidáme nový kód pro vykreslení produktů a formulář pro zadání začátku názvu produktu:
Po spuštění služby OData a MVC aplikace si prohlédneme výsledky v prohlížeči na adrese https://localhost:5102/. V tomto případě by se měly zobrazit tři produkty, jejichž názvy začínají písmeny "Cha". Pokud změníme hodnotu v textovém poli a stiskneme Enter, aplikace vrátí pouze produkty, které začínají novým písmenem.
Dále můžeme otestovat komplexní dotaz na službu OData. Vytvoříme soubor odata-final-query.http a pomocí nástroje RestClient otestujeme následující dotaz:
Výsledek tohoto dotazu bude obsahovat produkty, jejichž název obsahuje řetězec "ch" a cena je nižší než 44,95, seřazené podle dodavatele a ceny.
Důležité je si uvědomit, že OData umožňuje velmi flexibilní práci s daty na serveru a minimalizuje objem přenášených dat mezi serverem a klientem. Filtrování a třídění dat na serveru může výrazně zvýšit výkon aplikace, protože se minimalizuje potřeba zpracovávat velké objemy dat na straně klienta. Uživatelé by měli také chápat, jak správně definovat požadavky na data v URL (pomocí různých parametrů OData), což je klíčové pro správnou interakci s API.
Jak využít GraphQL pro kombinování dat z více zdrojů
V oblasti moderní webové vývoje se stále častěji setkáváme s potřebou integrace různých datových zdrojů do jedné aplikace. Jedním z efektivních nástrojů pro tuto úlohu je GraphQL, který umožňuje flexibilní dotazování a manipulaci s daty. Tento přístup se ukáže jako obzvlášť užitečný při práci s více datovými zdroji, jak ukazuje následující příklad integrace GraphQL do aplikace .NET.
Ve složce Models jsme vytvořili tři nové třídy, které nám pomáhají s organizací dat, která budeme potřebovat pro naše uživatelské rozhraní. Začneme definováním třídy ResponseProducts, která bude uchovávat produkty, které patří do určité kategorie. Struktura této třídy je jednoduchá: obsahuje vnořenou třídu DataProducts, která má vlastnost ProductsInCategory, což je pole produktů. Tato třída je navržena tak, aby byla schopná přijímat data ve formátu, který poskytuje GraphQL server.
Podobně byla definována i třída ResponseCategories, která uchovává informace o kategoriích produktů. Je opět strukturována tak, že vnořená třída DataCategories obsahuje pole kategorií.
Dále jsme přistoupili k vytvoření třídy IndexViewModel, která bude sloužit jako model pro naši stránku, kde se budou zobrazovat produkty a kategorie. Tento model obsahuje různé vlastnosti pro uchovávání informací, jako jsou HTTP status kód, surový odpovědní text, produkty, kategorie a chyby.
Pro správnou komunikaci s GraphQL serverem jsme v souboru Program.cs přidali registraci HTTP klienta, který bude komunikovat s naším GraphQL serverem. Tento klient bude připraven pro odesílání POST požadavků s GraphQL dotazy, kde tělo požadavku bude obsahovat samotný GraphQL dotaz v JSON formátu.
Ve třídě HomeController.cs definujeme pole pro uchování HTTP klienta, který bude použit pro odesílání požadavků na GraphQL server. V konstruktoru třídy HomeController je klient inicializován prostřednictvím dependency injection.
V samotné metodě Index jsme přidali asynchronní volání pro komunikaci s GraphQL serverem. Nejprve provádíme GET požadavek na kořenovou adresu služby, abychom zjistili, zda server funguje správně. Poté odesíláme POST požadavek na GraphQL endpoint, kde v těle požadavku specifikujeme dotaz na produkty v určité kategorii.
Tato metoda nejen že zajišťuje komunikaci s GraphQL serverem, ale také správně zpracovává odpověď a zobrazuje chyby, pokud se nějaké vyskytly.
V samotné šabloně Index.cshtml jsme připravili zobrazení, které vykresluje produkty a kategorie na základě získaných dat. Pokud došlo k nějakým chybám, uživatel je o nich informován a mohou být zobrazeny podrobnosti o každé chybě, včetně cesty, kde k chybě došlo.
Při práci s GraphQL je kladeno velké důraz na správné formulování dotazů a manipulaci s odpověďmi. Důležité je nejen správně formulovat GraphQL dotaz, ale i správně zpracovávat odpovědi a efektivně vykreslovat data uživatelskému rozhraní. Výhody GraphQL spočívají ve flexibilitě dotazování a možnosti kombinovat data z různých zdrojů do jednoho odpovědního objektu.
Jak se vypořádat s městským prostředím a zachovat svou identitu
Jak geometrie a ornamentika odráží komplexnost světa
Jak příroda Selborne ovlivňuje krajinu a život lidí
Jaké tajemství se skrývá za podivným chováním Olivie?

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский