mcpField
M
maui-blazor-development

maui-blazor-development

github.com/ibutters開発380 回インストール46 週間前に更新
リポジトリ

maui-blazor-development について

maui-blazor-developmentは、クロスプラットフォームの.NET MAUI Blazorアプリの設計と開発を支援するスキルです。アーキテクチャ選択、ネイティブ機能、状態管理、ナビゲーションを扱います。

主な機能

  1. 01プラットフォームとアプリ構成の検討
  2. 02MAUIとBlazorのプロジェクト設定
  3. 03依存性注入のパターン
  4. 04ネイティブ機能へのアクセス
  5. 05ライフサイクル・状態・ナビゲーションのガイダンス

活用シーン

  1. 01モバイルと共有Web UI向けテンプレートの選択
  2. 02デバイスAPIと権限の統合
  3. 03状態管理とナビゲーション方式の選択

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/ibutters/claudecodeplugins --skill maui-blazor-development

インストール後、Claude Code で/maui-blazor-developmentを入力して読み込まれたか確認します。

詳細

.NET MAUI Blazor ハイブリッド開発

.NET MAUI と Blazor を使用したクロスプラットフォームアプリの開発に関する専門的なガイダンスです。

実装ワークフロー

1. 分析フェーズ(必須)

実装の前に、以下を確認します。

  • アプリの種類:MAUI Blazor のみ、または MAUI + Blazor Web App(UI を共有)
  • 対象プラットフォーム:Android、iOS、Windows、macOS
  • 必要なネイティブ機能:センサー、カメラ、ファイルシステム、通知
  • 状態管理:コンポーネントの状態、MVVM、またはハイブリッド方式
  • ナビゲーションパターン:Blazor のみ、Shell、または混合ナビゲーション
2. アーキテクチャの決定
シナリオ推奨される方法
モバイルファーストで、一部に Web を含むmaui-blazor テンプレート
モバイルと Web で UI を共有RCL を使った maui-blazor-web テンプレート
複雑なネイティブ連携プラットフォームサービスを使った MVVM
シンプルなデータ駆動型 UIDI サービスを使ったコンポーネントの状態
3. プロジェクトのセットアップ
// 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 の構成

<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>

コアパターン

依存性注入
ライフタイム使用例
AddSingleton<T>アプリ全体の状態、デバイスサービス、設定
AddScoped<T>BlazorWebView インスタンスごとの状態
AddTransient<T>ステートレスなユーティリティ、ファクトリー
// 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>();
コンポーネントのライフサイクル
@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
        }
    }
}
プラットフォーム機能へのアクセス
// 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
        }
    }
}
外部イベントからの状態更新
@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;
    }
}

リファレンスドキュメント

詳しいパターンや例については、以下を参照してください。

クイックリファレンス

よく使うサービス登録
// 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>();
プラットフォームの判定
// 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
ナビゲーションパターン
// 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");

コメント