Claude-skill-registry-data maui-blazor-development
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry-data
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry-data "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/maui-blazor-development" ~/.claude/skills/majiayu000-claude-skill-registry-data-maui-blazor-development && rm -rf "$T"
manifest:
data/maui-blazor-development/SKILL.mdsource content
.NET MAUI Blazor Hybrid Development
Expert guidance for building cross-platform apps with .NET MAUI and Blazor.
Implementation Workflow
1. Analysis Phase (Required)
Before implementation, determine:
- App type: Pure MAUI Blazor or MAUI + Blazor Web App (shared UI)
- Platform targets: Android, iOS, Windows, macOS
- Native features needed: Sensors, camera, file system, notifications
- State management: Component state, MVVM, or hybrid approach
- Navigation pattern: Blazor-only, Shell, or mixed navigation
2. Architecture Decision
| Scenario | Recommended Approach |
|---|---|
| Mobile-first with some web | template |
| Shared UI across mobile + web | template with RCL |
| Complex native integration | MVVM with platform services |
| Simple data-driven UI | Component state with DI services |
3. Project Setup
// MauiProgram.cs - Essential setup public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); }); builder.Services.AddMauiBlazorWebView(); #if DEBUG builder.Services.AddBlazorWebViewDeveloperTools(); #endif // Register services builder.Services.AddSingleton<IDeviceService, DeviceService>(); builder.Services.AddScoped<IDataService, DataService>(); return builder.Build(); }
4. BlazorWebView Configuration
<!-- MainPage.xaml --> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:b="clr-namespace:Microsoft.AspNetCore.Components.WebView.Maui;assembly=Microsoft.AspNetCore.Components.WebView.Maui"> <b:BlazorWebView HostPage="wwwroot/index.html"> <b:BlazorWebView.RootComponents> <b:RootComponent Selector="#app" ComponentType="{x:Type local:Main}" /> </b:BlazorWebView.RootComponents> </b:BlazorWebView> </ContentPage>
Core Patterns
Dependency Injection
| Lifetime | Use Case |
|---|---|
| App-wide state, device services, settings |
| Per-BlazorWebView instance state |
| Stateless utilities, factories |
// Interface for platform-specific implementation public interface IDeviceService { string GetDeviceModel(); Task<bool> HasPermissionAsync(string permission); } // Platform implementation registered in MauiProgram.cs builder.Services.AddSingleton<IDeviceService, DeviceService>();
Component Lifecycle
@code { [Parameter] public string Id { get; set; } = ""; // Called once when component initializes protected override async Task OnInitializedAsync() { await LoadDataAsync(); } // Called when parameters change (including first render) protected override void OnParametersSet() { // React to parameter changes } // Called after each render protected override void OnAfterRender(bool firstRender) { if (firstRender) { // JS interop safe here } } }
Platform Feature Access
// Check platform and access native features @inject IDeviceService DeviceService @if (DeviceInfo.Current.Platform == DevicePlatform.Android) { <AndroidSpecificComponent /> } @code { private async Task AccessCameraAsync() { var status = await Permissions.CheckStatusAsync<Permissions.Camera>(); if (status != PermissionStatus.Granted) { status = await Permissions.RequestAsync<Permissions.Camera>(); } if (status == PermissionStatus.Granted) { // Use camera } } }
State Updates from External Events
@implements IDisposable @inject IDataService DataService <p>@message</p> @code { private string message = ""; protected override void OnInitialized() { DataService.OnDataChanged += HandleDataChanged; } private async void HandleDataChanged(object? sender, EventArgs e) { message = "Data updated!"; await InvokeAsync(StateHasChanged); // Required for external events } public void Dispose() { DataService.OnDataChanged -= HandleDataChanged; } }
Reference Documentation
For detailed patterns and examples, see:
- Project Structure: Solution templates, RCL setup, multi-targeting
- Blazor Components: Lifecycle, RenderFragment, EventCallback, data binding
- Platform Integration: Device APIs, permissions, platform-specific code
- Navigation & Routing: Blazor routing, Shell, deep linking
- State Management: MVVM, DI patterns, CommunityToolkit.Mvvm
Quick Reference
Common Service Registration
// Services builder.Services.AddSingleton<ISettingsService, SettingsService>(); builder.Services.AddSingleton<IConnectivity>(Connectivity.Current); builder.Services.AddSingleton<IGeolocation>(Geolocation.Default); // ViewModels (if using MVVM) builder.Services.AddTransient<MainViewModel>(); builder.Services.AddTransient<SettingsViewModel>(); // Pages with DI builder.Services.AddTransient<MainPage>();
Platform Checks
// Runtime platform check if (DeviceInfo.Current.Platform == DevicePlatform.iOS) { } if (DeviceInfo.Current.Platform == DevicePlatform.Android) { } if (DeviceInfo.Current.Platform == DevicePlatform.WinUI) { } if (DeviceInfo.Current.Platform == DevicePlatform.macOS) { } // Compile-time platform check #if ANDROID // Android-specific code #elif IOS // iOS-specific code #elif WINDOWS // Windows-specific code #endif
Navigation Patterns
// Blazor navigation (within BlazorWebView) @inject NavigationManager Navigation Navigation.NavigateTo("/details/123"); // MAUI navigation (to other pages) await Navigation.PushAsync(new SettingsPage()); await Shell.Current.GoToAsync("//settings");