V předchozím příkladu je projekt pojmenován MyMauiApp a jeho ovládací prvky, jako je ovládací prvek CustomerList, jsou definovány v prostoru názvů MyMauiApp.Controls. Tento prostor názvů je registrován s prefixem „local“, takže když je potřeba instanci ovládacího prvku CustomerList, je deklarována pomocí tohoto prefixu. Stejně tak můžete importovat více prostorů názvů s různými prefixy podle potřeby.
Typové konvertory konvertují hodnoty atributů XAML, které musí být nastaveny jako řetězce, na jiné typy. Například následující tlačítko má nastavený atribut pozadí na hodnotu řetězce „Pink“. Tento proces zjednodušuje syntaxi, jak ukazuje následující markup:
Takové jednoduché přiřazení hodnoty může výrazně zjednodušit práci s XAML, zvláště když chcete používat typy, které se běžně používají pro styling v aplikacích. Tento způsob definování vzhledu je ale jen jednou z možností, jak si usnadnit vývoj v .NET MAUI.
Pokud se rozhodnete vytvořit mobilní aplikaci, která bude fungovat pouze na iPhonech, můžete využít jazyky Objective-C nebo Swift s knihovnami UIKit a nástrojem pro vývoj Xcode. Naopak, pro Android aplikace byste mohli použít jazyky Java nebo Kotlin a Android SDK prostředí v Android Studiu. Co ale dělat, když potřebujete vytvořit mobilní aplikaci, která poběží jak na iPhonech, tak na zařízeních Android? A co když chcete tuto aplikaci vytvořit pouze jednou, s jazykem a platformou, kterou již dobře znáte?
.NET MAUI (Multi-platform App UI) vám umožňuje vytvářet mobilní aplikace, které poběží na iOS, iPadOS, macOS (pomocí Catalyst), Windows (s využitím WinUI 3) a Androidu. Výhodou tohoto frameworku je, že můžete použít jazyk C# a platformu .NET, což vám umožní spustit aplikaci na nativních API různých platforem. Co je ještě silnějším argumentem pro jeho použití, je fakt, že logika aplikace (business logic) může být napsána pouze jednou a sdílena mezi všemi platformami.
Pro uživatelské rozhraní se však musíte přizpůsobit rozdílům mezi mobilními a desktopovými platformami. U některých aplikací se tedy může stát, že rozhraní bude muset být pro každou platformu upraveno tak, aby odpovídalo jejím specifikám. .NET MAUI používá XAML pro definování uživatelského rozhraní, a to tak, že abstrahuje specifické komponenty pro každou platformu, což zjednodušuje proces vývoje aplikací pro více systémů.
I když aplikace vytvořené pomocí .NET MAUI vypadají jako nativní aplikace díky využívání nativních widgetů platformy, není zážitek vždy úplně stejný jako u aplikací vytvořených specificky pro danou platformu. Nicméně pro aplikace, které nebudou mít miliony uživatelů, může být .NET MAUI dostatečné. S trochou úsilí lze navíc vytvořit krásné aplikace, jak ukazuje výzva Microsoftu, která je popsána na následujícím odkazu: https://devblogs.microsoft.com/dotnet/announcing-dotnet-maui-beautiful-ui-challenge/
Vývoj mobilních aplikací je dnes často podpořen službami v cloudu. Satya Nadella, CEO společnosti Microsoft, v této souvislosti prohlásil, že „mobilita aplikací“ není o mobilitě samotného zařízení, ale o mobilitě uživatelského zážitku. Dnes je klíčové, že pro orchestraci mobilních aplikací a dat je nezbytný cloud. Jak již bylo zmíněno v této knize, pro vytvoření služby ASP.NET Core Web API pro mobilní aplikaci můžeme použít Visual Studio Code. Pro vývoj aplikací pomocí .NET MAUI mohou vývojáři využívat Visual Studio 2022 pro Windows nebo Visual Studio 2022 pro Mac.
Pokud si chcete nainstalovat Visual Studio 2022, při instalaci musíte vybrat vývojovou pracovní zátěž .NET Multi-platform App UI development, která se nachází v sekci Desktop & Mobile. Tento krok je nezbytný, aby bylo možné vytvářet aplikace pro různé platformy pomocí .NET MAUI.
Pokud budete používat .NET MAUI, měli byste vědět, že vývoj aplikací pro mobilní zařízení dnes znamená přítomnost ve všech typech zařízení, nejen na mobilních telefonech. To, jak dobře vaše aplikace bude fungovat a vypadat, závisí na schopnosti správně přizpůsobit rozhraní různým platformám a zařízení. S vývojem pro více platforem se otevírá nové pole pro kreativitu a flexibilitu, kde se možnosti neomezují pouze na jedno prostředí. Zároveň však stále platí, že pokud budete chtít dosáhnout nejlepšího možného uživatelského zážitku, budete muset některé prvky aplikace přizpůsobit specifickým požadavkům dané platformy.
Jak pracovat s многозадачностью и синхронизацией в C#
V программировании с многозадачностью важно понимать, как эффективно управлять задачами и их состоянием. В данном контексте мы рассмотрим несколько ключевых аспектов многозадачности и синхронизации в C#, включая создание вложенных задач, ожидание их завершения и управление доступом к общим ресурсам.
Для начала рассмотрим создание задач с помощью библиотеки Task. Например, в классе Program.Methods.cs добавляем два метода, один из которых запускает другой. В данном случае, внешний метод запускает внутренний метод, используя Task.Factory.StartNew():
Этот пример демонстрирует создание двух задач: одна запускает другую. Внешний метод завершится раньше, чем внутренний, так как он не зависит от его завершения. Однако важно помнить, что это не влияет на фактическое завершение самой задачи. При запуске приложения результат будет выглядеть следующим образом:
При этом можно заметить, что внутренний метод может завершиться только после завершения внешнего. Однако для того, чтобы задачи стали взаимосвязанными как родительская и дочерняя, необходимо использовать опцию TaskCreationOptions.AttachedToParent, которая гарантирует завершение внутренней задачи до завершения внешней:
Теперь результат работы программы будет выглядеть так:
Здесь, как и следовало ожидать, программа не завершится до тех пор, пока не завершится внутренняя задача.
Оборачивание задач вокруг других объектов
Иногда необходимо сделать метод асинхронным, но результат выполнения не является задачей. В таких случаях можно использовать статические методы Task для оборачивания результата в уже завершённую задачу. Эти методы полезны для работы с интерфейсами, которые требуют возврата задачи, но при этом сама реализация метода является синхронной.
Методы FromResult, FromException и FromCanceled позволяют создавать задачи с заданным результатом или исключением:
-
Task.FromResult(TResult)— создаёт задачу с результатом, который не является задачей. -
Task.FromException(Exception)— создаёт задачу, завершённую с исключением. -
Task.FromCanceled(CancellationToken)— создаёт задачу, завершённую с учётом отмены.
Эти методы полезны, например, при реализации интерфейсов, требующих асинхронных методов, несмотря на то, что реализация метода может быть синхронной.
Пример реализации интерфейса с использованием Task.FromResult:
Здесь метод IsValidXmlTagAsync возвращает результат в виде задачи, несмотря на то, что сам метод выполняется синхронно.
Синхронизация доступа к общим ресурсам
Когда несколько потоков работают одновременно, существует риск одновременного доступа к общим ресурсам, что может привести к ошибкам. Для того чтобы избежать таких ситуаций, необходимо использовать механизмы синхронизации, такие как блокировки.
Самый простой способ обеспечить безопасность при многозадачности — это использовать объект, который будет служить флагом или сигналом для блокировки доступа к общим ресурсам. Примером такого объекта может быть "ракушка" (вдохновлено произведением Вильяма Голдинга "Повелитель мух"), которая используется для синхронизации доступа.
Для синхронизации доступов к ресурсу можно использовать Monitor или Interlocked. Например, чтобы безопасно изменять переменные в многозадачном окружении, можно применить Monitor:
В этом примере два метода MethodA и MethodB обращаются к общему ресурсу — строковой переменной Message, добавляя в неё символы "A" и "B". Для синхронизации этих операций можно применить блокировку, чтобы избежать одновременного доступа.
Для запуска этих методов на отдельных потоках и ожидания их завершения, можно использовать Task:
Важные аспекты, которые следует учитывать при работе с многозадачностью:
-
Важно правильно настроить синхронизацию задач, чтобы избежать состояний гонки, когда несколько потоков пытаются одновременно получить доступ к одному и тому же ресурсу.
-
Использование
TaskCreationOptions.AttachedToParentпозволяет убедиться, что дочерняя задача завершится до того, как завершится родительская. -
Статические методы
Task.FromResult,Task.FromExceptionи другие дают возможность интегрировать синхронные методы в асинхронные интерфейсы, что полезно для разработки и тестирования.
Jak testovat a zabezpečit webové služby pomocí REST Client a Minimal APIs
Pokud používáte Visual Studio Code, začněte tím, že nainstalujete REST Client od Huachao Mao (humao.rest-client), pokud jej ještě nemáte nainstalovaný. Poté spusťte projekt Northwind.WebApi.Service pomocí profilu https, pokud již není spuštěn, a ponechte ho aktivní. V adresáři apps-services-net7 vytvořte složku RestClientTests, pokud tam již neexistuje, a otevřete ji.
V této složce vytvořte soubor webapi-get-products.http, jehož obsah bude obsahovat požadavek na získání všech produktů. Tento požadavek může vypadat například takto:
Klikněte na Send Request a všimněte si, že odpověď bude stejná jako ta vrácená pomocí Swaggeru – tedy JSON dokument, který obsahuje prvních deset produktů, které jsou skladem a nejsou zrušeny.
V souboru webapi-get-products.http můžete přidat další požadavky oddělené ###, například:
Po kliknutí na Send Request u každého požadavku můžete obdržet odpověď podle jednotlivých kritérií. Požadavky můžete také spustit pomocí klávesové zkratky nebo příkazu Rest Client: Send Request z palety příkazů ve Visual Studio Code.
Dále vytvořte soubor webapi-insert-product.http, který bude obsahovat POST požadavek pro vložení nového produktu do databáze. Tento soubor může vypadat takto:
Po odeslání tohoto požadavku by měla odpověď ukázat kód 201, což znamená, že produkt byl úspěšně přidán. V odpovědi najdete ID nového produktu, například ID 81, a můžete si všimnout, že produkt byl přidán jako poslední v řadě.
Pokud chcete produkt upravit, vytvořte soubor webapi-update-product.http a použijte PUT požadavek k úpravě existujícího produktu, například produktu s ID 81. Tento požadavek může vypadat takto:
Po odeslání tohoto požadavku by měla odpověď vrátit kód 204, což znamená, že produkt byl úspěšně aktualizován. Ověřte to opětovným provedením GET požadavku pro tento produkt.
Pokud chcete produkt smazat, vytvořte soubor webapi-delete-product.http a použijte DELETE požadavek pro smazání produktu s ID 81:
Po odeslání požadavku byste měli obdržet odpověď, která potvrzuje úspěšné smazání produktu.
Pokud znovu odešlete DELETE požadavek na tento produkt, odpověď by měla obsahovat kód 404, což znamená, že produkt již neexistuje.
Pokud jde o specifické nastavení pro Swagger a OpenAPI dokumentaci, můžete například v Program.cs ve vašem ASP.NET Core projektu vyloučit určité cesty z dokumentace:
Tato cesta nebude viditelná v dokumentaci Swagger, přesto však zůstane funkční pro aplikace, které na ni pošlou požadavek.
Relaxace bezpečnostní politiky stejného původu pomocí CORS
Moderní webové prohlížeče umožňují uživatelům otevřít více karet, čímž mohou navštívit více webových stránek současně. Pokud by kód běžící na jedné kartě mohl přistupovat k prostředkům na jiné kartě, stalo by se to bezpečnostní hrozbou. Pro tento účel webové prohlížeče implementují same-origin policy (politiku stejného původu). To znamená, že pouze požadavky, které pocházejí ze stejného původu (domény, portu a protokolu), jsou povoleny. Jakýkoliv požadavek z jiného původu selže.
Pokud chcete tuto politiku relaxovat a povolit přístup z jiných původů, použijete CORS (Cross-Origin Resource Sharing). Tento mechanismus umožňuje serverům specifikovat, jaké zdroje mohou být přístupné z jiných domén.
Nastavení HTTP logování pro webovou službu
Pro sledování požadavků, které přicházejí do vaší webové služby, je užitečné povolit HTTP logování, které umožňuje zaznamenávat hlavičky požadavků, včetně hlavičky Origin, a odpovědi na tyto požadavky. V souboru Program.cs přidejte následující kód:
Díky tomu budete moci sledovat, odkud požadavky přicházejí, a co se vrací jako odpověď.

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