mcpField
M
maui-platform-invoke

maui-platform-invoke

github.com/davidortinau開発17648 回インストール16 週間前に更新
リポジトリ

maui-platform-invoke について

maui-platform-invokeは、.NET MAUI開発者向けにプラットフォーム固有コードの実装方法を説明するスキルです。分割クラスやインターフェースの使い分けと、よくある注意点を扱います。

主な機能

  1. 01プラットフォームコードの構成選択
  2. 02分割クラスによる実装
  3. 03インターフェースでの実装分離
  4. 04条件付きコンパイルの問題回避
  5. 05AndroidのActivity null対応

活用シーン

  1. 01プラットフォーム固有のサービスロジック構成
  2. 02共有コードの単体テスト容易化
  3. 03プラットフォーム別コンパイルとフォールバックの確認

インストール

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

$npx skills add https://github.com/davidortinau/maui-skills --skill maui-platform-invoke

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

同梱ファイルreferences/platform-invoke-api.md

詳細

Platform Invoke — 注意点とベストプラクティス

判断フレームワーク

シナリオアプローチ
1~5 行の一時的なチェック#if ANDROID 条件付きコンパイル
ロジックがあり、テスト可能なサービスPlatforms/ フォルダー内の部分クラス
実装の切り替えやモックが必要インターフェイス + DI 登録
*.android.cs 形式のファイル名をチームで採用している.csproj 内のカスタムファイルパターン

デフォルトの選択肢:部分クラス + インターフェイス + DI。 #if は簡単なインラインチェックにのみ使用してください。

よくある間違い

1. #if ディレクティブの多用
// ❌ Complex logic buried in #if blocks — untestable, hard to read
public async Task<bool> CheckConnectivity()
{
#if ANDROID
    // 30 lines of Android networking code...
#elif IOS
    // 25 lines of iOS networking code...
#endif
}

// ✅ Use partial classes — each platform file is clean and testable
// Services/ConnectivityService.cs (shared)
public partial class ConnectivityService
{
    public partial Task<bool> CheckConnectivityAsync();
}
// Platforms/Android/Services/ConnectivityService.cs
public partial class ConnectivityService
{
    public partial Task<bool> CheckConnectivityAsync() { /* Android impl */ }
}
2. 部分クラス間での名前空間の不一致

すべての部分クラスファイルで同じ名前空間を使用する必要があります。そうしないと、別々のクラスになります。

// ❌ Different namespaces — creates TWO unrelated classes
// Services/MyService.cs
namespace MyApp.Services;
public partial class MyService { }

// Platforms/Android/MyService.cs
namespace MyApp.Platforms.Android;  // WRONG!
public partial class MyService { }

// ✅ Same namespace everywhere
namespace MyApp.Services;
public partial class MyService { }
3. 共有コードで具象クラスに依存する
// ❌ Shared code depends on concrete platform type — can't mock in tests
public class MyViewModel
{
    readonly DeviceOrientationService _service = new();
}

// ✅ Depend on interface — enables unit testing and swapping
public class MyViewModel
{
    readonly IDeviceOrientationService _service;
    public MyViewModel(IDeviceOrientationService service) => _service = service;
}
4. #else のフォールバックを忘れる
// ❌ Fails compilation on unsupported platforms
public string GetDeviceName()
{
#if ANDROID
    return Android.OS.Build.Model;
#elif IOS
    return UIKit.UIDevice.CurrentDevice.Name;
#endif  // No return for Windows or other platforms!
}

// ✅ Always include a fallback
#else
    return "Unknown";
#endif

プラットフォーム固有の注意点

⚠️ Android:Platform.CurrentActivity が null になることがあります

Platform.CurrentActivity は、OnCreate の完了前やアプリがバックグラウンドにあるときに null になります。必ず null チェックを行うか、明確な例外をスローしてください。

⚠️ MSBuild は Platforms/{Platform}/ 内のファイルを自動的にインクルードします

Platforms/Android/ 内のファイルは Android 用にのみコンパイルされるため、#if は不要です。 ただし、プラットフォームコードを共有フォルダー(例:Services/)に置く場合は、#if または条件付きの <Compile> 項目を必ず使用してください。

⚠️ カスタムファイルパターンには明示的な MSBuild 条件が必要です

*.android.cs 形式のファイル名を使用する場合、ファイルは自動的にインクルードされません。.csproj にプラットフォーム条件付きの <Compile> 項目を追加してください。

チェックリスト

  • すべての部分クラスファイルで同じ名前空間を使用している
  • 複雑なプラットフォームコードには #if ブロックではなく部分クラスを使用している
  • 共有コードは具象実装ではなくインターフェイスに依存している
  • インターフェイスが MauiProgram.cs で DI に登録されている
  • #if ブロックに、サポート対象外のプラットフォーム向けの #else フォールバックが含まれている
  • Platform.CurrentActivity の使用前に null チェックを行っている(Android)
  • カスタムファイルパターンを使用している場合、MSBuild の <Compile> 条件を設定している

コメント