maui-platform-invoke について
maui-platform-invokeは、.NET MAUI開発者向けにプラットフォーム固有コードの実装方法を説明するスキルです。分割クラスやインターフェースの使い分けと、よくある注意点を扱います。
主な機能
- 01プラットフォームコードの構成選択
- 02分割クラスによる実装
- 03インターフェースでの実装分離
- 04条件付きコンパイルの問題回避
- 05AndroidのActivity null対応
活用シーン
- 01プラットフォーム固有のサービスロジック構成
- 02共有コードの単体テスト容易化
- 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>条件を設定している
コメント
Markdown 対応