Posted on 15. July 2023

Анонс .NET 8 Preview 6

 

 

Ми раді повідомити вам про найновіші функції та вдосконалення, доступні в .NET 8 Preview 6 ! Цей випуск є продовженням випуску Preview 5 , і ми прагнемо надавати вам все більше вдосконалень з кожним місячним випуском.

 

Сьогодні ми маємо справу із захоплюючим релізом з великою кількістю оновлень бібліотеки, новим режимом WASM, більшою кількістю генераторів джерел, постійними покращеннями продуктивності та підтримкою NativeAOT на iOS. Сподіваємося, вам сподобаються ці нові функції та вдосконалення. Слідкуйте за новинами, оскільки ми продовжуємо наш шлях до покращення .NET разом!


Ви можете завантажити .NET 8 Preview 6 для Linux, macOS і Windows.


Будьте в курсі новинок у .NET 8 . Він оновлюватиметься протягом випуску.


А тепер поглянемо на нові функції .NET 8.

 

Покращення System.Text.Json

Ми внесли низку вдосконалень у генератор вихідних кодів System.Text.Json, головним чином спрямованих на те, щоб Native AOT порівнявся з серіалізатором на основі відображення.

- Додано підтримку кешування для інкрементного генератора, що покращує продуктивність IDE у великих проєктах. https://github.com/dotnet/runtime/pull/86121 

- Покращене форматування згенерованого вихідного коду, включно з виправленням ряду проблем із відступами https://github.com/dotnet/runtime/pull/86526 , https://github.com/dotnet/runtime/pull/87557 

- Додано ряд нових діагностичних попереджень https://github.com/dotnet/runtime/pull/87980

- Виправлено ряд помилок, пов’язаних із роздільною здатністю модифікатора доступності https://github.com/dotnet/runtime/pull/87136 

- Гарантія, що типи ігнорованих або недоступних властивостей не включені генератором https://github.com/dotnet/runtime/pull/87383 

- Виправлено проблеми, пов’язані з підтримкою JsonNumberHandling https://github.com/dotnet/runtime/pull/87484 

- Виправлено підтримку рекурсивних типів колекцій https://github.com/dotnet/runtime/pull/87632 

- Виправлено підтримку спеціального конвертера для структур, що допускають значення NULL https://github.com/dotnet/runtime/pull/84208 

- Виправлено ряд помилок у реалізації синтаксичного аналізу атрибутів під час компіляції https://github.com/dotnet/runtime/pull/87796 

 

- Додано підтримку вкладеності декларацій JsonSerializerContext в довільних типах https://github.com/dotnet/runtime/pull/87829

 

JsonStringEnumConverter<TEnum>

Цей новий конвертер доповнює наявний клас JsonStringEnumConverter, який не підтримується в Native AOT.

Користувачі, які бажають націлитися на користувачів Native AOT, повинні анотувати свої типи переліків наступним шаблоном.

 

 

JsonConverter.Type

 

 

Нова властивість дозволяє користувачам шукати тип незагального образу JsonConverter:

 

Властивість має значення NULL, оскільки повертає null для екземплярів JsonConverterFactory і для typeof(T)екземплярів JsonConverter<T>.

 

Перевантаження методів ZipFile CreateFromDirectory та ExtractToDirectory на основі потоку

Ми додали нові перевантаження ZipFile.CreateFromDirectory, які дозволяють користувачам збирати всі файли, включені в каталог, і архівувати їх, а потім зберігати отриманий файл zip у наданому потоці.

Симетрично ми додали перевантаження ZipFile.ExtractToDirectory, які дозволяють користувачам надавати потік, що містить архівований файл, і витягувати його вміст у файлову систему.

Ці API дозволяють уникнути необхідності використовувати диск як проміжний крок. Це може бути корисним у ситуаціях, коли дисковий простір обмежений, як, наприклад, у хмарних середовищах:

- CreateFromDirectory дозволяє не записувати заархівований результат на диск.

 

- ExtractToDirectory не вимагає, щоб заархівований файл знаходився на диску.

 Використання ZipFile.CreateFromDirectory

 

Використання ZipFile.ExtractToDirectory


Метрики API MetricCollector

MetricCollector — це новий клас, призначений для тестування сценаріїв. Раніше він називався InstrumentRecorder. Ми значно вдосконалили цей клас і перемістили його в пакет Microsoft.Extensions.Telemetry.Testing .

Тепер клас MetricCollector може записувати метричні вимірювання разом із часовими мітками. Крім того, клас пропонує гнучкість використання будь-якого бажаного постачальника часу для точного створення позначок часу.

 

Наступний приклад демонструє, як використовувати цю функцію.

Використання MetricCollector

Представляємо генератор джерела перевірки параметрів

Щоб зменшити витрати на запуск і покращити набір функцій перевірки, ми представили генератор вихідного коду , який реалізує логіку перевірки.


Використання перевірки параметрів


Якщо програма використовує ін’єкцію залежностей, вона може ін’єктувати перевірку за таким шаблоном.

 

Розширення перевантажень конструктора LoggerMessageAttribute для підвищення функціональності


Були введені нові LoggerMessageAttribute перевантаження конструктора, які пропонують більшу гнучкість у визначенні необхідних параметрів за допомогою скорочення коду. Нові перевантаження конструктора включають такі параметри, як визначення лише LogLevel і повідомлення, лише LogLevel або лише повідомлення.


Ці вдосконалення полегшують користувачам визначення атрибутів LoggerMessageAttributes, мінімізуючи непотрібний код.

 

Використання LoggerMessage

 

Наступний приклад демонструє реалізацію LoggerMessage, яка раніше була неможлива.

 

Примітка : у пізнішому прев’ю, для конструкторів, яким не потрібен ідентифікатор події, система автоматично згенерує ідентифікатор події, усуваючи потребу вручну надавати його користувачам.

 

Покращення генератора джерела прив’язки конфігурації

У Прев’ю № 3 ми представили новий джерельний генератор для забезпечення AOT і зручної конфігурації в ASP.NET Core . Генератор є альтернативою існуючій реалізації на основі відображення. Відтоді ми внесли кілька покращень на основі відгуків спільноти, і генератор готовий, щоб люди могли спробувати його ще раз за допомогою Preview 6.


Приклад програми , яка використовує зв’язування конфігурації та публікується з AOT, змінюється від двох (2) попереджень аналізу AOT під час компіляції до жодного. ДДодаток не працював при виконанні, але тепер він працює.


Для використання генератора не потрібно змінювати вихідний код. Його ввімкнено за замовчуванням у веб-програмах Native AOT. Для інших типів проектів його вимкнено за замовчуванням, але ви можете керувати ним, додавши наступну властивість до свого проекту.

Ви можете знайти відомі проблеми тут .

 

Генерований джерелом COM Interop


Тепер у нас є новий джерельний генератор, який підтримує взаємодію з COM-інтерфейсами за допомогою підтримки взаємодії, створеної джерелом , з якої ми почали LibraryImportAttribute. Ви можете використовувати System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute, щоб позначити інтерфейс як інтерфейс COM для вихідного генератора. Потім генератор вихідного коду згенерує код, щоб увімкнути виклик із коду C# до некерованого коду, а також код, щоб увімкнути виклик із некерованого коду в C#. Цей джерельний генератор інтегрується з LibraryImportAttribute, і ви можете використовувати типи з параметрами GeneratedComInterfaceAttribute  і повертати типи в методах LibraryImportAttributе.

 

 

Генератор вихідних кодів COM забезпечує зрозумілий досвід роботи з IDE через аналізатори та виправлення коду. Це схоже на LibraryImportAttribute. Біля кожного інтерфейсу, який має System.Runtime.InteropServices.ComImportAttribute, лампочка пропонуватиме опцію перетворення на взаємодію, згенеровану джерелом. Це виправлення змінить інтерфейс для використання GeneratedComInterfaceAttribute. Біля кожного класу, який реалізує інтерфейс із GeneratedComInterfaceAttribute, лампочка запропонує опцію додати GeneratedComClassAttribute до типу. Після перетворення типів ви можете використовувати  свої методи DllImport, щоб використати LibraryImportAttribute з наявним там засобом виправлення коду. За допомогою цих двох лампочок можна легко перетворити наявний код взаємодії COM для використання нового взаємодії, створеного джерелом. Також є більше аналізаторів, які допомагають виявити місця, де ви можете змішувати COM-взаємодію, згенеровану джерелом, і на основі середовища виконання, що може потребувати додаткової роботи.

 

 

У рамках цього проекту ми оновили бібліотеку System.Transactions для використання нової взаємодії, створеної джерелом! Ми використали цей досвід, щоб допомогти вдосконалити аналізатори та засоби виправлення коду, щоб забезпечити якісний досвід міграції.

 

Використання GeneratedComInterface

 

GeneratedComClassAttribute

 

Генератор вихідного коду також підтримує новий System.Runtime.InteropServices.Marshalling.GeneratedComClassAttribute , щоб дозволити вам передавати ваші типи, які реалізують інтерфейси з System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute - атрибутованих інтерфейсів до некерованого коду. Генератор вихідного коду згенерує код, необхідний для надання COM-об’єкта, який реалізує інтерфейси та перенаправляє виклики до керованої реалізації.

 

Використання GeneratedComClassAttribute

 

Взаємодія з LibraryImportAttribute


Методи в інтерфейсах з підтримкою GeneratedComInterfaceAttribute всіх тих самих типів, що й LibraryImportAttribute, і LibraryImportAttribute отримують підтримку для атрибутованих типів GeneratedComInterface та  атрибутованих типів GeneratedComClass в цьому випуску.

Якщо у вашому коді C# використовуватиметься лише GeneratedComInterfaceAttribute - атрибутований інтерфейс або для обгортання COM-об’єкта з некерованого коду, або для обгортання керованого об’єкта з C# для некерованого коду, ви можете використовувати параметри у властивості GeneratedComInterfaceAttribute.Options, щоб налаштувати, який код буде згенеровано. Цей параметр дозволить вам не писати маршаллери для сценаріїв, які, як ви знаєте, не використовуватимуться.

 

Генератор джерела використовує новий тип System.Runtime.InteropServices.Marshalling.StrategyBasedComWrappers для створення та керування оболонками об’єктів COM і оболонками керованих об’єктів. Цей новий тип забезпечує очікувану взаємодію .NET з COM-взаємодією, а також надає точки налаштування для досвідчених користувачів. Якщо ваша програма має власний механізм для визначення типів із COM або якщо вам потрібно підтримувати сценарії, які наразі не підтримує COM, створений джерелом, ви можете розглянути можливість використання нового типу StrategyBasedComWrappers, щоб додати відсутні функції для вашого сценарію та отримати той самий .NET досвід користувача для ваших типів COM.

Обмеження

На цю мить вихідний генератор COM має такі обмеження. Ми не плануємо усувати ці обмеження в .NET 8, але можливо в майбутній версії .NET.

Немає підтримки інтерфейсів на основі IDispatch.

Підтримка цих інтерфейсів може бути реалізована вручну за допомогою локального визначення інтерфейсу IDispatch.

– Немає підтримки інтерфейсів на основі IInspectable.

Використовуйте інструмент CsWinRT , щоб створити код взаємодії для цих інтерфейсів.

– Немає підтримки спорідненості апартаментів.

Передбачається, що всі COM-об’єкти є безпотоковими. Підтримку спорідненості апартаментів можна впровадити вручну за допомогою реалізацій типу StrategyBasedComWrappers та спеціальної стратегії.

– Немає підтримки властивостей COM.

Вони можуть бути реалізовані вручну як методи в інтерфейсі.

– Немає підтримки подій COM.

Вони можуть бути реалізовані вручну за допомогою базових API COM.

– Не підтримується використання ключового слова new для активації COM CoClass.

 

Використовуйте LibraryImportAttribute для P/Invoke до CoCreateInstance API, щоб активувати CoClass.

Підтримка HTTPS проксі

https://github.com/dotnet/runtime/issues/31113

Хоча HttpClient деякий час підтримував різні типи проксі, усі вони дозволяють людині посередині бачити, до якого сайту підключається клієнт. (навіть для HTTPS URI) Проксі-сервер HTTPS дозволяє створити зашифрований канал між клієнтом і проксі-сервером, щоб усі наступні запити могли оброблятися з повною конфіденційністю.

Використання проксі HTTPS

– Unix: export all_proxy=https://x.x.x.x:3218

– Windows: set all_proxy=https://x.x.x.x:3218

 

Цим також можна керувати програмно через WebProxy .

 

System.Security: підтримка SHA-3

Підтримка примітивів хешування SHA-3 тепер доступна на платформах, які пропонують SHA-3. Зараз це Linux із OpenSSL 1.1.1+ і Windows 11 build 25324+.

API, де доступний SHA-2, тепер пропонують доповнення SHA-3. Воно містить SHA3_256, SHA3_384 і SHA3_512 для хешування; HMACSHA3_256, HMACSHA3_384, і HMACSHA3_512 для HMAC; HashAlgorithmName.SHA3_256, HashAlgorithmName.SHA3_384, та HashAlgorithmName.SHA3_512 для хешування, де алгоритм можна налаштувати; і RSAEncryptionPadding.OaepSHA3_256, RSAEncryptionPadding.OaepSHA3_384, та RSAEncryptionPadding.OaepSHA3_512 для шифрування RSA OAEP.

Використання API SHA-3 подібне до SHA-2, з додаванням властивості IsSupported, щоб визначити, чи пропонує платформа SHA-3.

Крім того, SHA-3 включає дві функції розширюваного виведення (XOF), SHAKE128 і SHAKE256. Вони доступні як Shake128і Shake256.

 

Підтримка SHA-3 наразі спрямована на підтримку криптографічних примітивів. Очікується, що конструкції та протоколи вищого рівня спочатку не повністю підтримуватимуть SHA-3. Це включає, але не обмежується сертифікатами X.509 SignedXmlі COSE. Підтримка SHA-3 може розширитися в майбутньому залежно від підтримки платформи та стандартів, які використовують SHA-3.

 

SHA-3 був стандартизований NIST як FIPS 202 як альтернатива, а не наступник SHA-2. Розробники та організації повинні вирішити, коли й навіть чи підходить їм прийняття SHA-3.

SDK: продуктивність і сумісність публікації контейнерів

Ми внесли кілька змін до стандартних значень створених зображень для програм .NET 8.


– Зображення тепер за замовчуванням використовують нову безкореневу можливість контейнерів .NET , що робить ваші програми безпечними за замовчуванням. Ви можете будь-коли змінити це, встановивши власний ContainerUser, як root.

– Зображення позначені тегами latest за замовчуванням, як і інші інструменти для контейнерів.


Ми покращили продуктивність надсилання контейнерів до віддалених реєстрів, надійність операції надсилання та підтримку більшого діапазону реєстрів. У той же час Том Десейн з Red Hat був зайнятий вдосконаленням нашої підтримки для ряду поширених реалізацій контейнерів.


У цій версії має бути значно покращена продуктивність для надсилання контейнерів, особливо до реєстрів Azure. Це саме завдяки нашій покращеній підтримці просування шарів за одну операцію. Крім того, для реєстрів, які не підтримують атомарне завантаження, ми запровадили більш надійний механізм завантаження фрагментів, який можна повторити.


Як побічний ефект цих змін ми також розширили нашу матрицю підтримки для реєстрів. Harbor і Artifactory приєдналися до списку відомих працюючих реєстрів, а робота Тома також уможливила запуск Quay.io і Podman.

 

Режим HybridGlobalization на WASM

 

Програми WASM можуть використовувати новий режим глобалізації, який полегшує пакет ICU та натомість використовує веб-API. У гібридному режимі дані глобалізації частково витягуються з пакета ICU, а частково – із викликів у JS. Він обслуговує всі регіони, які підтримує WASM .

 

Коли розглядати можливість використання HybridGlobalization

 

Цей параметр найбільше підходить для програм, які не можуть працювати в режимі InvariantGlobalization та використовувати дані локалізації з кількох сегментів ICU (EFIGS, CJK, no-CJK), тому наразі використовується:

у Blazor WebAssembly або

у браузері WASM.

Програми, які завантажували no-CJK або CJK shard за допомогою спеціального методу завантаження файлу ICU :
також може бути цікаво, тому що гібридний файл менший за фрагмент без CJK на 26% і менший за CJK на 15%.

Як використовувати HybridGlobalization

Установіть властивість MsBuild: <HybridGlobalization>true</HybridGlobalization>. Він завантажить файл icudt_hybrid.dat, який на 46% менший, ніж початково завантажений icudt.dat.

Обмеження

Через обмеження веб-API не всі API глобалізації підтримуються в гібридному режимі. Деякі з підтримуваних API змінили свою поведінку. Щоб переконатися, що це не вплине на вашу програму, прочитайте розділ Поведінкові відмінності для WASM .


API, які отримують результат шляхом звернення до JS, мають гіршу продуктивність, ніж негібридна версія. Ці API перераховані в документації . Інтерфейси API, яких немає в списках «Уражені публічні API», працюють так само, як і в негібридному режимі.

 

Підтримка націлювання на платформи iOS за допомогою NativeAOT

Тепер ми маємо підтримку націлювання на iOS-подібні платформи за допомогою Native AOT. Сюди входить створення й запуск програм .NET iOS, .NET MAUI а також NativeAOT з такими системами: ios, iossimulator, maccatalyst, tvos або tvossimulator. Мотивація цієї роботи полягає в тому, щоб дозволити користувачам вивчити можливість досягнення кращої продуктивності та економії розміру при орієнтації на такі платформи за допомогою. 

 

Ця функція доступна як додаткова функція, призначена для розгортання програми, коли Mono все ще використовується як вибір середовища виконання за умовчанням для розробки та розгортання програми. Ця віха була досягнута завдяки чудовій співпраці між членами нашої спільноти: @filipnavara @AustinWise та @am11 , які зробили внесок своєю роботою та спільними зусиллями NativeAOT, Mono і Xamarin команд.

Поточний стан

Поточний стан перевірено за допомогою:

.NET iOS app( )dotnet new ios

.NET MAUI iOS app( )dotnet new maui

 

Ці зразки програм показують такі попередні результати порівняно з Mono:

Результати .NET 8 Preview 6  (позначені як *-p6) показують, що .NET iOS app має значні покращення порівняно з Mono, де пакет стисненого додатка (.ipa) досяг на ~39% меншого розміру, демонструючи великий потенціал, тоді як .NET MAUI iOS app показує гірші результати, створюючи на ~13% гірший результат. Однак ми визначили основну причину регресії розміру за допомогою програми .NET MAUI, і наразі ми працюємо над таким списком проблем, щоб усунути регресію розміру:

1. https://github.com/xamarin/xamarin-macios/pull/18532

2. https://github.com/xamarin/xamarin-macios/issues/18479 

3. https://github.com/dotnet/runtime/issues/87924 

4. https://github.com/dotnet/runtime/issues/86649 

Ми оцінили, що усунувши виявлені проблеми 1-3), NativeAOT може досягти чудових результатів із додатком .NET MAUI, який показано в стовпці NativeAOT-fix, де розмір пакета додатків менший на  ~30%  порівняно з Mono. Виправлення проблеми 4) може ще більше покращити продуктивність, але на даному етапі ми не можемо оцінити точні цифри. Більше інформації про продуктивність .NET MAUI з NativeAOT відстежується на: https://github.com/dotnet/runtime/issues/80907

Відзначимо, що висновки щодо продуктивності NativeAOT на iOS-подібних платформах не слід робити ні з наведених у таблиці чисел, ні з випуску .NET 8 Preview 6 в цілому. Тим паче, що це все ще триває і це лише перший крок до того, щоб зробити функцію готовою до офіційного випуску .NET 9. Тому ми активно працюємо над удосконаленнями та визначаємо всю роботу, яка намагатиметься надати нашим клієнтам повний досвід NativeAOT для досягнення високої продуктивності та економії розміру, що відстежується в наведеному нижче списку проблем (та їхніх підзавдань):

– https://github.com/dotnet/runtime/issues/80905 tracks: Загальний прогрес

– https://github.com/xamarin/xamarin-macios/issues/17339 tracks: покращення інтеграції Xamarin

 

– https://github.com/dotnet/runtime/issues/86649 tracks: Покращення сумісності з обрізанням і розширеннями=

 

Як створити та запустити програму .NET MAUI за допомогою NativeAOT на пристрої iOS із .NET CLI

Встановлення

Створення образу програми

Вибір NativeAOT замість Mono

Властивості MSBuild PublishAot=true і PublishAotUsingRuntimePack=true (тимчасові, див. нижче) дозволяють розгортання NativeAOT.

Ці дві властивості є єдиною помітною відмінністю в порівнянні з розгортанням за допомогою Mono. Вам потрібно додати їх у PropertyGroup файлу проєкту вашої програми:

Це означає, що щоразу, коли програму розгортають через dotnet publish, вона розгортатиметься за допомогою NativeAOT.

Запуск програми

Сумісність з iOS і NativeAOT

Не всі функції iOS сумісні з NativeAOT. Так само не всі бібліотеки, які зазвичай використовуються в iOS, сумісні з NativeAOT. .NET 8 означає початок роботи над увімкненням NativeAOT для iOS. Ваші відгуки допоможуть нам спрямовувати наші зусилля під час попереднього перегляду .NET 8 і далі, щоб ми зосередилися на тих місцях, де переваги NativeAOT можуть мати найбільший вплив.

У наведеному нижче списку є деякі обмеження під час націлювання на iOS-подібні платформи, які зустрічалися досі (тому це може бути не остаточний список):

– Встановлення та розгортання програми за допомогою Visual Studio ще не перевірено

Використання NativeAOT ввімкнено лише під час розгортання програми dotnet publish

Функціональні можливості бібліотеки Linq.Expressions ще не повністю підтримуються

Властивість MSBuild PublishAotUsingRuntimePack=true — це тимчасовий обхідний шлях, необхідний для націлювання на iOS-подібні платформи за допомогою NativeAOT 

Ця вимога стане неактуальною після виправлення: https://github.com/dotnet/runtime/issues/87060

Налагодження керованого коду підтримується лише з Mono

 

ПРИМІТКА. Попередній список є розширенням обмежень, які застосовуються до всіх платформ NativeAOT: https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/limitations.md

Резюме

.NET 8 Preview 6 містить захоплюючі нові функції та вдосконалення, які були б неможливі без наполегливої ​​роботи та відданості різноманітної команди інженерів Microsoft і пристрасної спільноти відкритих програм. Ми хочемо висловити нашу щиру подяку всім, хто зробив внесок у .NET 8 до цього часу , чи то через внески коду, звіти про помилки чи надання відгуків.

 

Ваш внесок відіграв важливу роль у створенні попереднього перегляду .NET 8, і ми з нетерпінням чекаємо на продовження спільної роботи, щоб побудувати світле майбутнє для .NET і всієї технологічної спільноти.

 

Source