Start Debugging

.NET MAUI 10.0.100 добавляет UsePlatformHandler для собственных бэкендов BlazorWebView

В MAUI 10.0.100 появился MauiBlazorWebViewBuilderExtensions.UsePlatformHandler, поддерживаемая точка расширения для замены BlazorWebViewHandler без повторной реализации всего, что регистрирует AddMauiBlazorWebView(). Две перегрузки и одна ловушка с порядком вызовов.

.NET MAUI 10.0.100 вышел 2026-08-20 и содержит 209 коммитов, большая часть которых является обычным содержимым сервисного выпуска: регрессии прокрутки в CollectionView, отступы безопасной области во флайауте Shell на Android, iOS-овский ActivityIndicator, который отказывался исчезать. Однако в этом списке спрятан по-настоящему новый публичный API, и он разблокирует целую категорию проектов, застрявших с момента выхода Blazor Hybrid: MauiBlazorWebViewBuilderExtensions.UsePlatformHandler.

Почему AddMauiBlazorWebView() был тупиком для собственных платформ

AddMauiBlazorWebView() выполняет две задачи. Он регистрирует общую инфраструктуру, которая нужна любому BlazorWebView (JSInterop, навигация, разрешение статических ресурсов), и жёстко задаёт BlazorWebViewHandler в качестве обработчика для IBlazorWebView.

Проблема была во второй задаче. Если вы делали бэкенд для платформы, для которой MAUI не поставляет обработчиков (мотивирующим примером был GTK-рендерер для Linux), встроенный обработчик вам просто не подходил, а точки расширения для его замены не существовало. В issue #34103 описан обходной путь, к которому в итоге пришли: полностью пропустить AddMauiBlazorWebView(), вручную заново зарегистрировать каждый внутренний сервис, а затем догонять эти регистрации всякий раз, когда они меняются в апстриме.

Новая точка расширения

PR #34225 добавляет два метода расширения для IMauiBlazorWebViewBuilder:

public static IMauiBlazorWebViewBuilder UsePlatformHandler<THandler>(
    this IMauiBlazorWebViewBuilder builder)
    where THandler : IViewHandler, new();

public static IMauiBlazorWebViewBuilder UsePlatformHandler(
    this IMauiBlazorWebViewBuilder builder,
    Func<IServiceProvider, IViewHandler> factory);

В MauiProgram.cs весь этот обходной путь сворачивается до одного вызова в цепочке:

builder.Services
    .AddMauiBlazorWebView()
    .UsePlatformHandler<GtkBlazorWebViewHandler>();

Всё, что регистрирует AddMauiBlazorWebView(), остаётся на месте. Меняется только обработчик. Внутри метод перенаправляет вызов в ConfigureMauiHandlers(h => h.AddHandler<IBlazorWebView, THandler>()), то есть в ту же коллекцию обработчиков, в которую пишет встроенная регистрация.

Обратите внимание на обобщённое ограничение: where THandler : IViewHandler, new(). Параметр типа дополнительно помечен атрибутом [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)], чтобы тримминг сохранял конструктор без параметров в обрезанной сборке или в сборке с NativeAOT, а не удалял его молча. Обработчики, которым нужны аргументы конструктора, проходят через фабричную перегрузку.

Порядок вызовов является острым краем

Замена работает по правилу “побеждает последняя регистрация”, и это режет в обе стороны. Вызывайте UsePlatformHandler после AddMauiBlazorWebView(), иначе он ничего не сделает. Ещё неприятнее другое: если нижележащая библиотека позже в вашем конвейере запуска снова вызовет AddMauiBlazorWebView(), этот второй вызов заново зарегистрирует обработчик по умолчанию, и ваш бэкенд исчезнет без ошибки и без предупреждения. Когда конфигурация MAUI Blazor собирается из нескольких источников, вызывайте UsePlatformHandler последним.

У фабричной перегрузки есть вторая ловушка, о которой стоит знать. IServiceProvider, который она передаёт, является провайдером фабрики обработчиков MAUI, а не корневым провайдером приложения. Он разрешает только сервисы, зарегистрированные через ConfigureMauiHandlers, и ничего больше, поэтому попытка достать оттуда синглтон уровня приложения завершится неудачей.

Обеих перегрузок нет в Microsoft.AspNetCore.Components.WebView.Maui 10.0.90 и они присутствуют в 10.0.100, так что это прямое пополнение 10.0.100, а не тихий бэкпорт. Если вы следите за поездом сервисных выпусков .NET MAUI 10, то выкатка Material 3 на Android завершилась ещё в SR6.

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Назад