Claude Skill

dotnet-uno-platform

Build cross-platform .NET applications with Uno Platform targeting WebAssembly, iOS, Android, macOS, Linux, and Windows from a single XAML/C# codebase.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download postpartum-genushyacinthus29-dotnet-skills-skills_dotnet-uno-platform-bfa4ebd.zip · 5 KB
Part of postpartum-genushyacinthus29/dotnet-skills — 80 skills

Install

skills CLI npx skills add https://github.com/Postpartum-genushyacinthus29/dotnet-skills/tree/main/skills/dotnet-uno-platform
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install postpartum-genushyacinthus29-dotnet-skills@llmmart
Git git clone https://github.com/Postpartum-genushyacinthus29/dotnet-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole postpartum-genushyacinthus29/dotnet-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Uno Platform

Trigger On

  • building cross-platform apps from a single C# and XAML codebase
  • targeting WebAssembly, iOS, Android, macOS, Linux, and Windows simultaneously
  • migrating WPF or UWP applications to cross-platform
  • implementing pixel-perfect UI across all platforms
  • using WinUI/UWP APIs on non-Windows platforms

Documentation

References

See detailed examples in the references/ folder:

  • patterns.md — MVUX, XAML, navigation, and performance patterns

Platform Support

Platform Rendering Notes
Windows WinUI 3 Native Windows App SDK
WebAssembly Skia/Canvas Runs in browser
iOS Skia/Metal Native iOS app
Android Skia/OpenGL Native Android app
macOS Skia/Metal Mac Catalyst or AppKit
Linux Skia/X11 GTK or Framebuffer

Workflow

  1. Choose the right template — Uno Platform offers various templates for different scenarios
  2. Understand rendering modes — Skia vs native rendering affects performance and fidelity
  3. Apply MVVM or MVUX patterns — keep views dumb, logic in ViewModels
  4. Handle platform differences — use conditional XAML or partial classes
  5. Test on all target platforms — behavior varies across platforms

Project Structure

MyApp/
├── MyApp/                    # Shared code
│   ├── App.xaml              # Application entry
│   ├── MainPage.xaml         # Main page
│   ├── Presentation/         # ViewModels (MVUX/MVVM)
│   ├── Business/             # Business logic
│   └── Services/             # Platform services
├── MyApp.Wasm/               # WebAssembly head
├── MyApp.Mobile/             # iOS and Android head
├── MyApp.Skia.Gtk/           # Linux head
├── MyApp.Skia.WPF/           # Windows Skia head
└── MyApp.Windows/            # Native WinUI head

MVUX Pattern (Uno Extensions)

Model Definition

public partial record MainModel
{
    public IListFeed<TodoItem> Items => ListFeed.Async(LoadItems);

    private async ValueTask<IImmutableList<TodoItem>> LoadItems(CancellationToken ct)
    {
        var items = await _todoService.GetAllAsync(ct);
        return items.ToImmutableList();
    }
}

View Binding with FeedView

<Page xmlns:uen="using:Uno.Extensions.Navigation.UI">
    <utu:FeedView Source="{Binding Items}">
        <utu:FeedView.ValueTemplate>
            <DataTemplate>
                <ListView ItemsSource="{Binding}">
                    <ListView.ItemTemplate>
                        <DataTemplate x:DataType="local:TodoItem">
                            <TextBlock Text="{Binding Title}" />
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </DataTemplate>
        </utu:FeedView.ValueTemplate>
        <utu:FeedView.ProgressTemplate>
            <DataTemplate>
                <ProgressRing IsActive="True" />
            </DataTemplate>
        </utu:FeedView.ProgressTemplate>
    </utu:FeedView>
</Page>

Classic MVVM with MVVM Toolkit

ViewModel

public partial class MainViewModel(ITodoService todoService) : ObservableObject
{
    [ObservableProperty]
    private ObservableCollection<TodoItem> _items = [];

    [ObservableProperty]
    private bool _isLoading;

    [RelayCommand]
    private async Task LoadItemsAsync()
    {
        IsLoading = true;
        try
        {
            var items = await todoService.GetAllAsync();
            Items = new ObservableCollection<TodoItem>(items);
        }
        finally
        {
            IsLoading = false;
        }
    }
}

Platform-Specific Code

Conditional XAML

<TextBlock Text="Welcome"
           xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:android="http://uno.ui/android"
           xmlns:ios="http://uno.ui/ios"
           xmlns:wasm="http://uno.ui/wasm">

    <win:TextBlock.Foreground>
        <SolidColorBrush Color="Blue" />
    </win:TextBlock.Foreground>

    <android:TextBlock.Foreground>
        <SolidColorBrush Color="Green" />
    </android:TextBlock.Foreground>
</TextBlock>

Partial Classes

// Services/DeviceService.cs (shared)
public partial class DeviceService
{
    public partial string GetDeviceInfo();
}

// Services/DeviceService.wasm.cs
public partial class DeviceService
{
    public partial string GetDeviceInfo() => "WebAssembly";
}

// Services/DeviceService.Android.cs
public partial class DeviceService
{
    public partial string GetDeviceInfo() =>
        $"Android {Android.OS.Build.VERSION.Release}";
}

Hot Reload and Development

// Enable Hot Reload in App.xaml.cs
public App()
{
    this.InitializeComponent();

#if DEBUG
    // Enable Hot Reload
    this.EnableHotReload();
#endif
}

Anti-Patterns to Avoid

Anti-Pattern Why It's Bad Better Approach
Platform code in shared Breaks compilation Use partial classes or #if
Ignoring Skia differences Visual bugs Test on all renderers
WPF assumptions Not all APIs exist Check Uno API coverage
Heavy XAML Slow on WASM Virtualize, simplify
Synchronous loading UI freezes Always use async

Performance Best Practices

  1. Use virtualized lists:

    <ListView ItemsSource="{Binding Items}"
              VirtualizingPanel.VirtualizationMode="Recycling" />
    
  2. Lazy load resources:

    // Load images on demand
    var image = await ImageSource.LoadFromUriAsync(uri);
    
  3. Minimize XAML complexity:

    • Avoid deep nesting
    • Use compiled bindings (x:Bind where supported)
    • Consider Skia-specific optimizations
  4. WebAssembly specific:

    • Minimize interop calls
    • Use InvokeAsync for JS interop
    • Consider AOT compilation for performance

Uno Extensions

// Use Uno.Extensions for enhanced patterns
var builder = this.CreateBuilder(args)
    .Configure(host => host
        .UseConfiguration()
        .UseLocalization()
        .UseNavigation()
        .UseMvux()
        .ConfigureServices(services =>
        {
            services.AddSingleton<ITodoService, TodoService>();
        }));

Deliver

  • single codebase running on web, mobile, and desktop
  • consistent UI/UX across all platforms
  • platform-specific optimizations where needed
  • MVVM or MVUX patterns for testability

Validate

  • app builds and runs on all target platforms
  • platform-specific features work correctly
  • performance is acceptable on WebAssembly
  • Hot Reload works during development
  • no WPF/UWP-only APIs are used without fallbacks
Files (dotnet-skills)
  • references
    • patterns.md 10.5 KB
      # Uno Platform Patterns Reference
      
      ## MVUX Patterns
      
      ### Basic Model with Feed
      ```csharp
      public partial record ProductsModel(IProductService Products)
      {
          public IListFeed<Product> Items => ListFeed.Async(Products.GetAllAsync);
      }
      ```
      
      ### Model with State
      ```csharp
      public partial record ProductDetailModel(IProductService Products)
      {
          public IState<int> ProductId => State<int>.Empty(this);
      
          public IFeed<Product> Product => ProductId
              .SelectAsync(async (id, ct) => await Products.GetAsync(id, ct));
      }
      ```
      
      ### Model with Commands
      ```csharp
      public partial record OrderModel(IOrderService Orders)
      {
          public IState<string> CustomerName => State<string>.Value(this, () => string.Empty);
          public IState<string> ProductId => State<string>.Value(this, () => string.Empty);
          public IState<int> Quantity => State<int>.Value(this, () => 1);
      
          public async ValueTask SubmitOrder(CancellationToken ct)
          {
              var order = new Order
              {
                  CustomerName = await CustomerName,
                  ProductId = await ProductId,
                  Quantity = await Quantity
              };
              await Orders.CreateAsync(order, ct);
          }
      }
      ```
      
      ### Pagination Pattern
      ```csharp
      public partial record PaginatedModel(IProductService Products)
      {
          public IState<int> CurrentPage => State<int>.Value(this, () => 0);
          public IState<int> PageSize => State<int>.Value(this, () => 20);
      
          public IListFeed<Product> Items =>
              CurrentPage.CombineWith(PageSize)
                  .SelectAsync(async (state, ct) =>
                  {
                      var (page, size) = state;
                      return await Products.GetPageAsync(page, size, ct);
                  })
                  .AsListFeed();
      
          public async ValueTask NextPage()
          {
              await CurrentPage.Update(p => p + 1);
          }
      
          public async ValueTask PreviousPage()
          {
              await CurrentPage.Update(p => Math.Max(0, p - 1));
          }
      }
      ```
      
      ## XAML Patterns
      
      ### Responsive Layout
      ```xml
      <Grid>
          <VisualStateManager.VisualStateGroups>
              <VisualStateGroup>
                  <VisualState x:Name="Narrow">
                      <VisualState.StateTriggers>
                          <AdaptiveTrigger MinWindowWidth="0" />
                      </VisualState.StateTriggers>
                      <VisualState.Setters>
                          <Setter Target="MainContent.Orientation" Value="Vertical" />
                          <Setter Target="SidePanel.Visibility" Value="Collapsed" />
                      </VisualState.Setters>
                  </VisualState>
                  <VisualState x:Name="Wide">
                      <VisualState.StateTriggers>
                          <AdaptiveTrigger MinWindowWidth="800" />
                      </VisualState.StateTriggers>
                      <VisualState.Setters>
                          <Setter Target="MainContent.Orientation" Value="Horizontal" />
                          <Setter Target="SidePanel.Visibility" Value="Visible" />
                      </VisualState.Setters>
                  </VisualState>
              </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
      
          <StackPanel x:Name="MainContent">
              <Grid x:Name="SidePanel" Width="300" />
              <Grid x:Name="ContentPanel" />
          </StackPanel>
      </Grid>
      ```
      
      ### Platform-Specific Styling
      ```xml
      <Style TargetType="Button" x:Key="PlatformButton">
          <Setter Property="Padding" Value="16,8" />
      
          <!-- Windows-specific -->
          <win:Setter Property="CornerRadius" Value="4" />
      
          <!-- Android-specific -->
          <android:Setter Property="Background" Value="{StaticResource MaterialPrimary}" />
      
          <!-- iOS-specific -->
          <ios:Setter Property="Background" Value="{StaticResource iOSBlue}" />
      </Style>
      ```
      
      ### FeedView with All States
      ```xml
      <utu:FeedView Source="{Binding Products}">
          <!-- Loading state -->
          <utu:FeedView.ProgressTemplate>
              <DataTemplate>
                  <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                      <ProgressRing IsActive="True" Width="40" Height="40" />
                      <TextBlock Text="Loading..." Margin="0,8,0,0" />
                  </StackPanel>
              </DataTemplate>
          </utu:FeedView.ProgressTemplate>
      
          <!-- Error state -->
          <utu:FeedView.ErrorTemplate>
              <DataTemplate>
                  <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                      <SymbolIcon Symbol="Warning" />
                      <TextBlock Text="{Binding Message}" Margin="0,8,0,0" />
                      <Button Content="Retry" Command="{Binding RetryCommand}" />
                  </StackPanel>
              </DataTemplate>
          </utu:FeedView.ErrorTemplate>
      
          <!-- Empty state -->
          <utu:FeedView.NoneTemplate>
              <DataTemplate>
                  <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                      <SymbolIcon Symbol="List" />
                      <TextBlock Text="No items found" Margin="0,8,0,0" />
                  </StackPanel>
              </DataTemplate>
          </utu:FeedView.NoneTemplate>
      
          <!-- Success state -->
          <utu:FeedView.ValueTemplate>
              <DataTemplate>
                  <ListView ItemsSource="{Binding}">
                      <ListView.ItemTemplate>
                          <DataTemplate x:DataType="local:Product">
                              <Grid Padding="12">
                                  <TextBlock Text="{x:Bind Name}" />
                              </Grid>
                          </DataTemplate>
                      </ListView.ItemTemplate>
                  </ListView>
              </DataTemplate>
          </utu:FeedView.ValueTemplate>
      </utu:FeedView>
      ```
      
      ## Platform Service Patterns
      
      ### Abstracted Platform Service
      ```csharp
      // Shared interface
      public interface IPlatformService
      {
          string GetPlatformName();
          Task<bool> RequestPermissionAsync(string permission);
          Task ShareAsync(string text, string? title = null);
      }
      
      // Shared implementation with partial methods
      public partial class PlatformService : IPlatformService
      {
          public partial string GetPlatformName();
          public partial Task<bool> RequestPermissionAsync(string permission);
          public partial Task ShareAsync(string text, string? title = null);
      }
      ```
      
      ```csharp
      // Platforms/Android/PlatformService.cs
      public partial class PlatformService
      {
          public partial string GetPlatformName() => "Android";
      
          public async partial Task<bool> RequestPermissionAsync(string permission)
          {
              var status = await Permissions.RequestAsync<Permissions.StorageRead>();
              return status == PermissionStatus.Granted;
          }
      
          public async partial Task ShareAsync(string text, string? title)
          {
              var intent = new Intent(Intent.ActionSend);
              intent.SetType("text/plain");
              intent.PutExtra(Intent.ExtraText, text);
              Platform.CurrentActivity.StartActivity(Intent.CreateChooser(intent, title));
          }
      }
      ```
      
      ```csharp
      // Platforms/iOS/PlatformService.cs
      public partial class PlatformService
      {
          public partial string GetPlatformName() => "iOS";
      
          public async partial Task<bool> RequestPermissionAsync(string permission)
          {
              // iOS permission handling
          }
      
          public async partial Task ShareAsync(string text, string? title)
          {
              var controller = new UIActivityViewController(
                  new NSObject[] { new NSString(text) }, null);
              await UIApplication.SharedApplication.KeyWindow
                  .RootViewController.PresentViewControllerAsync(controller, true);
          }
      }
      ```
      
      ## Navigation Patterns
      
      ### Region-Based Navigation
      ```csharp
      // App.xaml.cs
      public App()
      {
          this.InitializeComponent();
      
          var builder = this.CreateBuilder(args)
              .Configure(host => host
                  .UseNavigation(RegisterRoutes));
      }
      
      void RegisterRoutes(IViewRegistry views, IRouteRegistry routes)
      {
          views.Register(
              new ViewMap<MainPage, MainModel>(),
              new ViewMap<ProductPage, ProductModel>(),
              new ViewMap<SettingsPage, SettingsModel>()
          );
      
          routes.Register(
              new RouteMap("", View: views.FindByViewModel<MainModel>()),
              new RouteMap("Product", View: views.FindByViewModel<ProductModel>()),
              new RouteMap("Settings", View: views.FindByViewModel<SettingsModel>())
          );
      }
      ```
      
      ### Navigation with Parameters
      ```csharp
      public partial record ProductListModel(INavigator Navigator)
      {
          public async ValueTask NavigateToProduct(Product product)
          {
              await Navigator.NavigateViewModelAsync<ProductModel>(
                  this, data: new { ProductId = product.Id });
          }
      }
      
      public partial record ProductModel(INavigator Navigator)
      {
          // Receives ProductId from navigation data
          public IState<int> ProductId => State<int>.Value(this, () => 0);
      }
      ```
      
      ## Performance Patterns
      
      ### Virtualized List
      ```xml
      <ListView ItemsSource="{Binding Items}"
                VirtualizingStackPanel.VirtualizationMode="Recycling"
                VirtualizingStackPanel.IsVirtualizing="True">
          <ListView.ItemsPanel>
              <ItemsPanelTemplate>
                  <ItemsStackPanel Orientation="Vertical" />
              </ItemsPanelTemplate>
          </ListView.ItemsPanel>
      </ListView>
      ```
      
      ### Deferred Loading
      ```xml
      <Grid>
          <!-- Load expensive content only when visible -->
          <Grid x:Name="ExpensiveContent"
                x:Load="{x:Bind ViewModel.ShowDetails, Mode=OneWay}">
              <local:ExpensiveUserControl />
          </Grid>
      </Grid>
      ```
      
      ### Image Optimization
      ```csharp
      // Use appropriate image sizes per platform
      public static ImageSource GetOptimizedImage(string basePath)
      {
      #if __ANDROID__
          var density = Android.Content.Res.Resources.System.DisplayMetrics.Density;
          var suffix = density switch
          {
              < 1.5f => "mdpi",
              < 2.0f => "hdpi",
              < 3.0f => "xhdpi",
              _ => "xxhdpi"
          };
          return ImageSource.FromFile($"{basePath}_{suffix}.png");
      #elif __IOS__
          return ImageSource.FromFile($"{basePath}@2x.png");
      #else
          return ImageSource.FromFile($"{basePath}.png");
      #endif
      }
      ```
      
      ## Theme Patterns
      
      ### Light/Dark Theme Support
      ```csharp
      public class ThemeService : IThemeService
      {
          public void SetTheme(AppTheme theme)
          {
              var resources = Application.Current.Resources;
              var mergedDictionaries = resources.MergedDictionaries;
      
              mergedDictionaries.Clear();
              mergedDictionaries.Add(theme switch
              {
                  AppTheme.Light => new LightTheme(),
                  AppTheme.Dark => new DarkTheme(),
                  _ => new SystemTheme()
              });
          }
      }
      ```
      
      ```xml
      <!-- LightTheme.xaml -->
      <ResourceDictionary>
          <Color x:Key="BackgroundColor">#FFFFFF</Color>
          <Color x:Key="TextColor">#000000</Color>
          <Color x:Key="AccentColor">#0078D4</Color>
      </ResourceDictionary>
      
      <!-- DarkTheme.xaml -->
      <ResourceDictionary>
          <Color x:Key="BackgroundColor">#1E1E1E</Color>
          <Color x:Key="TextColor">#FFFFFF</Color>
          <Color x:Key="AccentColor">#0078D4</Color>
      </ResourceDictionary>
      ```
      
  • SKILL.md 7.4 KB
    ---
    name: dotnet-uno-platform
    version: "1.0.0"
    category: "Cross-Platform UI"
    description: "Build cross-platform .NET applications with Uno Platform targeting WebAssembly, iOS, Android, macOS, Linux, and Windows from a single XAML/C# codebase."
    compatibility: "Requires Uno Platform SDK and workloads for target platforms."
    ---
    
    # Uno Platform
    
    ## Trigger On
    
    - building cross-platform apps from a single C# and XAML codebase
    - targeting WebAssembly, iOS, Android, macOS, Linux, and Windows simultaneously
    - migrating WPF or UWP applications to cross-platform
    - implementing pixel-perfect UI across all platforms
    - using WinUI/UWP APIs on non-Windows platforms
    
    ## Documentation
    
    - [Uno Platform Overview](https://platform.uno/docs/articles/intro.html)
    - [Getting Started](https://platform.uno/docs/articles/getting-started.html)
    - [Using Uno Platform with WinUI](https://platform.uno/docs/articles/winui-doc-links.html)
    - [Platform-Specific Code](https://platform.uno/docs/articles/platform-specific-xaml.html)
    - [MVUX Pattern](https://platform.uno/docs/articles/external/uno.extensions/doc/Overview/Mvux/Overview.html)
    
    ## References
    
    See detailed examples in the `references/` folder:
    - [`patterns.md`](references/patterns.md) — MVUX, XAML, navigation, and performance patterns
    
    ## Platform Support
    
    | Platform | Rendering | Notes |
    |----------|-----------|-------|
    | Windows | WinUI 3 | Native Windows App SDK |
    | WebAssembly | Skia/Canvas | Runs in browser |
    | iOS | Skia/Metal | Native iOS app |
    | Android | Skia/OpenGL | Native Android app |
    | macOS | Skia/Metal | Mac Catalyst or AppKit |
    | Linux | Skia/X11 | GTK or Framebuffer |
    
    ## Workflow
    
    1. **Choose the right template** — Uno Platform offers various templates for different scenarios
    2. **Understand rendering modes** — Skia vs native rendering affects performance and fidelity
    3. **Apply MVVM or MVUX patterns** — keep views dumb, logic in ViewModels
    4. **Handle platform differences** — use conditional XAML or partial classes
    5. **Test on all target platforms** — behavior varies across platforms
    
    ## Project Structure
    
    ```
    MyApp/
    ├── MyApp/                    # Shared code
    │   ├── App.xaml              # Application entry
    │   ├── MainPage.xaml         # Main page
    │   ├── Presentation/         # ViewModels (MVUX/MVVM)
    │   ├── Business/             # Business logic
    │   └── Services/             # Platform services
    ├── MyApp.Wasm/               # WebAssembly head
    ├── MyApp.Mobile/             # iOS and Android head
    ├── MyApp.Skia.Gtk/           # Linux head
    ├── MyApp.Skia.WPF/           # Windows Skia head
    └── MyApp.Windows/            # Native WinUI head
    ```
    
    ## MVUX Pattern (Uno Extensions)
    
    ### Model Definition
    ```csharp
    public partial record MainModel
    {
        public IListFeed<TodoItem> Items => ListFeed.Async(LoadItems);
    
        private async ValueTask<IImmutableList<TodoItem>> LoadItems(CancellationToken ct)
        {
            var items = await _todoService.GetAllAsync(ct);
            return items.ToImmutableList();
        }
    }
    ```
    
    ### View Binding with FeedView
    ```xml
    <Page xmlns:uen="using:Uno.Extensions.Navigation.UI">
        <utu:FeedView Source="{Binding Items}">
            <utu:FeedView.ValueTemplate>
                <DataTemplate>
                    <ListView ItemsSource="{Binding}">
                        <ListView.ItemTemplate>
                            <DataTemplate x:DataType="local:TodoItem">
                                <TextBlock Text="{Binding Title}" />
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </DataTemplate>
            </utu:FeedView.ValueTemplate>
            <utu:FeedView.ProgressTemplate>
                <DataTemplate>
                    <ProgressRing IsActive="True" />
                </DataTemplate>
            </utu:FeedView.ProgressTemplate>
        </utu:FeedView>
    </Page>
    ```
    
    ## Classic MVVM with MVVM Toolkit
    
    ### ViewModel
    ```csharp
    public partial class MainViewModel(ITodoService todoService) : ObservableObject
    {
        [ObservableProperty]
        private ObservableCollection<TodoItem> _items = [];
    
        [ObservableProperty]
        private bool _isLoading;
    
        [RelayCommand]
        private async Task LoadItemsAsync()
        {
            IsLoading = true;
            try
            {
                var items = await todoService.GetAllAsync();
                Items = new ObservableCollection<TodoItem>(items);
            }
            finally
            {
                IsLoading = false;
            }
        }
    }
    ```
    
    ## Platform-Specific Code
    
    ### Conditional XAML
    ```xml
    <TextBlock Text="Welcome"
               xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:android="http://uno.ui/android"
               xmlns:ios="http://uno.ui/ios"
               xmlns:wasm="http://uno.ui/wasm">
    
        <win:TextBlock.Foreground>
            <SolidColorBrush Color="Blue" />
        </win:TextBlock.Foreground>
    
        <android:TextBlock.Foreground>
            <SolidColorBrush Color="Green" />
        </android:TextBlock.Foreground>
    </TextBlock>
    ```
    
    ### Partial Classes
    ```csharp
    // Services/DeviceService.cs (shared)
    public partial class DeviceService
    {
        public partial string GetDeviceInfo();
    }
    
    // Services/DeviceService.wasm.cs
    public partial class DeviceService
    {
        public partial string GetDeviceInfo() => "WebAssembly";
    }
    
    // Services/DeviceService.Android.cs
    public partial class DeviceService
    {
        public partial string GetDeviceInfo() =>
            $"Android {Android.OS.Build.VERSION.Release}";
    }
    ```
    
    ## Hot Reload and Development
    
    ```csharp
    // Enable Hot Reload in App.xaml.cs
    public App()
    {
        this.InitializeComponent();
    
    #if DEBUG
        // Enable Hot Reload
        this.EnableHotReload();
    #endif
    }
    ```
    
    ## Anti-Patterns to Avoid
    
    | Anti-Pattern | Why It's Bad | Better Approach |
    |--------------|--------------|-----------------|
    | Platform code in shared | Breaks compilation | Use partial classes or #if |
    | Ignoring Skia differences | Visual bugs | Test on all renderers |
    | WPF assumptions | Not all APIs exist | Check Uno API coverage |
    | Heavy XAML | Slow on WASM | Virtualize, simplify |
    | Synchronous loading | UI freezes | Always use async |
    
    ## Performance Best Practices
    
    1. **Use virtualized lists:**
       ```xml
       <ListView ItemsSource="{Binding Items}"
                 VirtualizingPanel.VirtualizationMode="Recycling" />
       ```
    
    2. **Lazy load resources:**
       ```csharp
       // Load images on demand
       var image = await ImageSource.LoadFromUriAsync(uri);
       ```
    
    3. **Minimize XAML complexity:**
       - Avoid deep nesting
       - Use compiled bindings (`x:Bind` where supported)
       - Consider Skia-specific optimizations
    
    4. **WebAssembly specific:**
       - Minimize interop calls
       - Use `InvokeAsync` for JS interop
       - Consider AOT compilation for performance
    
    ## Uno Extensions
    
    ```csharp
    // Use Uno.Extensions for enhanced patterns
    var builder = this.CreateBuilder(args)
        .Configure(host => host
            .UseConfiguration()
            .UseLocalization()
            .UseNavigation()
            .UseMvux()
            .ConfigureServices(services =>
            {
                services.AddSingleton<ITodoService, TodoService>();
            }));
    ```
    
    ## Deliver
    
    - single codebase running on web, mobile, and desktop
    - consistent UI/UX across all platforms
    - platform-specific optimizations where needed
    - MVVM or MVUX patterns for testability
    
    ## Validate
    
    - app builds and runs on all target platforms
    - platform-specific features work correctly
    - performance is acceptable on WebAssembly
    - Hot Reload works during development
    - no WPF/UWP-only APIs are used without fallbacks
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related