---
name: maui-enterprise-architect
description: Thiết kế và xây dựng ứng dụng đa nền tảng .NET MAUI theo chuẩn Enterprise (MVVM, DI, Shell, Single Project). Use for mobile/desktop apps, cross-platform development, hoặc khi cần structured MAUI architecture.
compatibility: ".NET 9+ MAUI, CommunityToolkit.Mvvm 8+, CommunityToolkit.Maui 9+"
metadata:
  author: Velik Ho
  version: "1.0"
  references: "Microsoft .NET MAUI Documentation, Enterprise Application Patterns"
---

# .NET MAUI Enterprise Development Workflow

Quy trình 4 giai đoạn để phát triển ứng dụng .NET MAUI đa nền tảng theo chuẩn Enterprise.

## When to Use This Skill / Khi Nào Sử Dụng

Use this skill when:
- Building cross-platform mobile/desktop apps / Xây dựng app đa nền tảng
- Creating enterprise MAUI applications / Tạo ứng dụng MAUI enterprise
- Need MVVM + DI architecture / Cần kiến trúc MVVM + DI
- Implementing Shell-based navigation / Triển khai điều hướng Shell

**DO NOT use when:**
- Simple single-platform apps / App đơn giản 1 nền tảng
- Prototyping / Làm prototype nhanh
- Blazor Hybrid apps (use Blazor patterns) / App Blazor Hybrid

## Overview / Tổng Quan

```
┌──────────────────────────────────────────────────────────────────┐
│                 WORKFLOW 4 GIAI ĐOẠN (.NET MAUI)                 │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌─────────────┐     ┌─────────────────┐                        │
│  │   PHASE 1   │────►│     PHASE 2     │                        │
│  │  PROJECT    │     │   ARCHITECTURE  │                        │
│  │  STRUCTURE  │     │                 │                        │
│  │ - Single Prj│     │ - MVVM Pattern  │                        │
│  │ - Resources │     │ - DI Setup      │                        │
│  │ - Fonts     │     │ - ViewModels    │                        │
│  └─────────────┘     └────────┬────────┘                        │
│                               │                                  │
│                               ▼                                  │
│  ┌─────────────┐     ┌─────────────────┐                        │
│  │   PHASE 4   │◄────│     PHASE 3     │                        │
│  │  PLATFORM   │     │   UI & SHELL    │                        │
│  │             │     │                 │                        │
│  │ - Handlers  │     │ - AppShell      │                        │
│  │ - Platform  │     │ - Navigation    │                        │
│  │ - Native    │     │ - XAML Perf     │                        │
│  └─────────────┘     └─────────────────┘                        │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘
```

---

## Phase 1: Project Structure / Cấu Trúc Dự Án

**Goal**: Thiết lập Single Project MAUI với quản lý resources tối ưu

### Checklist

1. **Single Project Setup**
   - Một codebase cho Android, iOS, macOS, Windows
   - Platform-specific code trong `Platforms/` folder

2. **Resources Management**
   - Đặt images, fonts, icons vào `Resources/`
   - Sử dụng SVG cho icons (auto-resize)

3. **Font Registration**
   - Đăng ký fonts trong `MauiProgram.cs`

### Project Structure

```
MyApp/
├── App.xaml                    # Application resources
├── AppShell.xaml               # Navigation shell
├── MauiProgram.cs              # DI & configuration
├── Platforms/                  # Platform-specific code
│   ├── Android/
│   ├── iOS/
│   ├── MacCatalyst/
│   └── Windows/
├── Resources/
│   ├── Fonts/                  # Custom fonts
│   ├── Images/                 # App images (SVG preferred)
│   ├── Raw/                    # Raw assets
│   └── Styles/                 # XAML styles
├── ViewModels/                 # MVVM ViewModels
├── Views/                      # XAML Pages
├── Models/                     # Data models
└── Services/                   # Business services
```

---

## Phase 2: Architecture (MVVM + DI) / Kiến Trúc

**Goal**: Thiết lập MVVM pattern với Dependency Injection

**Detailed Guide**: [DI Setup Guidelines](./guidelines/di-setup.md) | [MVVM Rules](./guidelines/mvvm-rules.md)

### Key Patterns

```csharp
// MauiProgram.cs - DI Registration
public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .UseMauiCommunityToolkit()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("Inter-Regular.ttf", "InterRegular");
            fonts.AddFont("Inter-Bold.ttf", "InterBold");
        });

    // Services (Singleton for stateful, Transient for stateless)
    builder.Services.AddSingleton<IProductService, ProductService>();
    builder.Services.AddSingleton<INavigationService, NavigationService>();
    
    // ViewModels (Transient - new instance per navigation)
    builder.Services.AddTransient<ProductListViewModel>();
    builder.Services.AddTransient<ProductDetailViewModel>();
    
    // Views (Transient to match ViewModel lifecycle)
    builder.Services.AddTransient<ProductListPage>();
    builder.Services.AddTransient<ProductDetailPage>();

    return builder.Build();
}
```

```csharp
// ViewModel với CommunityToolkit.Mvvm
public partial class ProductListViewModel : ObservableObject
{
    private readonly IProductService _productService;
    
    [ObservableProperty]
    private ObservableCollection<Product> _products = new();
    
    [ObservableProperty]
    [NotifyCanExecuteChangedFor(nameof(RefreshCommand))]
    private bool _isLoading;
    
    public ProductListViewModel(IProductService productService)
    {
        _productService = productService;
    }
    
    [RelayCommand]
    private async Task LoadProductsAsync()
    {
        IsLoading = true;
        try
        {
            var items = await _productService.GetAllAsync();
            Products = new ObservableCollection<Product>(items);
        }
        finally
        {
            IsLoading = false;
        }
    }
    
    [RelayCommand]
    private async Task NavigateToDetailAsync(Product product)
    {
        await Shell.Current.GoToAsync(
            $"{nameof(ProductDetailPage)}",
            new Dictionary<string, object> { ["Product"] = product });
    }
}
```

---

## Phase 3: UI & Navigation (App Shell) / Giao Diện & Điều Hướng

**Goal**: Xây dựng UI với Shell navigation và XAML tối ưu

**Detailed Guide**: [Shell Navigation](./guidelines/shell-nav.md) | [XAML Performance](./guidelines/xaml-perf.md)

### AppShell Configuration

```xml
<!-- AppShell.xaml -->
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:views="clr-namespace:MyApp.Views"
       x:Class="MyApp.AppShell">
    
    <!-- Tab-based navigation -->
    <TabBar>
        <ShellContent Title="Products" 
                      Icon="products.svg"
                      ContentTemplate="{DataTemplate views:ProductListPage}" />
        <ShellContent Title="Settings" 
                      Icon="settings.svg"
                      ContentTemplate="{DataTemplate views:SettingsPage}" />
    </TabBar>
</Shell>
```

```csharp
// AppShell.xaml.cs - Route Registration
public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
        
        // Register routes for navigation
        Routing.RegisterRoute(nameof(ProductDetailPage), typeof(ProductDetailPage));
        Routing.RegisterRoute(nameof(EditProductPage), typeof(EditProductPage));
    }
}
```

### Compiled Bindings (BẮT BUỘC)

```xml
<!-- ✅ ĐÚNG: Compiled Bindings với x:DataType -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:MyApp.ViewModels"
             x:Class="MyApp.Views.ProductListPage"
             x:DataType="vm:ProductListViewModel">
    
    <CollectionView ItemsSource="{Binding Products}"
                    x:DataType="vm:ProductListViewModel">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="models:Product">
                <Grid Padding="10">
                    <Label Text="{Binding Name}" FontSize="16"/>
                    <Label Text="{Binding Price, StringFormat='{0:C}'}" 
                           Grid.Column="1"/>
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>
```

### Navigation with Parameters

```csharp
// Implement IQueryAttributable for receiving parameters
public partial class ProductDetailViewModel : ObservableObject, IQueryAttributable
{
    [ObservableProperty]
    private Product _product;
    
    public void ApplyQueryAttributes(IDictionary<string, object> query)
    {
        if (query.TryGetValue("Product", out var product))
        {
            Product = product as Product;
        }
    }
}
```

---

## Phase 4: Platform Integration / Tích Hợp Nền Tảng

**Goal**: Tùy chỉnh native controls và platform-specific code

### Handlers (NOT Custom Renderers)

```csharp
// Customize Entry control
public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .ConfigureMauiHandlers(handlers =>
        {
#if ANDROID
            handlers.AddHandler<Entry, CustomEntryHandler>();
#endif
        });
    
    return builder.Build();
}
```

### Platform-Specific Code (Partial Classes)

```csharp
// Services/DeviceService.cs (shared interface)
public partial class DeviceService : IDeviceService
{
    public partial string GetDeviceId();
}

// Platforms/Android/Services/DeviceService.cs
public partial class DeviceService
{
    public partial string GetDeviceId()
    {
        return Android.Provider.Settings.Secure.GetString(
            Android.App.Application.Context.ContentResolver,
            Android.Provider.Settings.Secure.AndroidId);
    }
}

// Platforms/iOS/Services/DeviceService.cs
public partial class DeviceService
{
    public partial string GetDeviceId()
    {
        return UIKit.UIDevice.CurrentDevice.IdentifierForVendor?.ToString() ?? "";
    }
}
```

---

## Common Mistakes / Lỗi Thường Gặp

| Mistake | Problem | Solution |
|---------|---------|----------|
| Logic in Code-behind | Hard to test, violates MVVM | Move to ViewModel |
| No `x:DataType` | Runtime binding, slow | Always use Compiled Bindings |
| Nested StackLayout | Deep visual tree, slow | Use Grid instead |
| Custom Renderers | Legacy Xamarin.Forms | Use Handlers |
| Singleton ViewModels | State persists wrongly | Use Transient for pages |
| `#if ANDROID` everywhere | Code pollution | Use Partial Classes |

## Quick Reference / Tham Chiếu Nhanh

| Category | Standard |
|----------|----------|
| Project Type | Single Project MAUI |
| MVVM Toolkit | CommunityToolkit.Mvvm |
| Navigation | Shell + URI-based |
| Bindings | Compiled (`x:DataType`) |
| Images | SVG preferred |
| Platform Code | Partial Classes / `Platforms/` |
| Control Customization | Handlers (not Renderers) |
| Service Lifetime | Singleton (stateful), Transient (pages) |

## Resources / Tài Nguyên

- [MVVM Rules](./guidelines/mvvm-rules.md) - ViewModel patterns
- [Shell Navigation](./guidelines/shell-nav.md) - Navigation patterns  
- [DI Setup](./guidelines/di-setup.md) - Dependency Injection
- [XAML Performance](./guidelines/xaml-perf.md) - Compiled Bindings & optimization
- [Microsoft MAUI Docs](https://learn.microsoft.com/en-us/dotnet/maui/)
- [CommunityToolkit.Mvvm](https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/)
- [Project Rules](../project-rules/SKILL.md) - GoodGo coding standards
