The Anatomy of an Uno Platform Solution

The Anatomy of an Uno Platform Solution

It’s been almost a month since I left home to attend the Microsoft MVP Summit in Seattle. I’m still on the road, currently in Athens, Greece, with numerous notes for upcoming articles. While traveling makes writing challenging, I want to maintain the order of my Uno Platform series to ensure everything makes sense for readers.

In this article, we’ll dive into the structure of an Uno Platform solution. There’s some “black magic” happening behind the scenes, so understanding how everything works will make development significantly easier.

What is Uno Platform?

Before we dive into the anatomy, let’s briefly explain what Uno Platform is. Uno Platform is an open-source framework that enables developers to build cross-platform applications from a single codebase. Using C# and XAML, you can create applications that run on Windows, iOS, Android, macOS, Linux, and WebAssembly.

Root Solution Structure

An Uno Platform solution follows a specific structure that facilitates cross-platform development. Let’s break down the key components:

Main (and only) Project

The core of an Uno Platform solution is the main shared project (in our example, “UnoAnatomy”). This project contains cross-platform code shared across all target platforms and includes:

  • Assets: Contains shared resources like images and icons used across all platforms. These assets may be adapted for different screen densities and platforms as needed.
  • Serialization: Here is where the JsonSerializerContext lives, Since .NET 6 serialization context allows controlling how objects are serialized through the JsonSerializerContext class. It provides ahead-of-time metadata generation for better performance and reduces reflection usage, particularly beneficial for AOT compilation scenarios like Blazor WebAssembly and native apps.
  • Models: Contains business model classes representing core domain entities in your application.
  • Presentation: Holds UI components including pages, controls, and views. This typically includes files like Shell.xaml.cs and MainPage.xaml.cs that implement the application’s UI elements and layout.
  • Platforms:
    • Android: Contains the Android-specific entry point (MainActivity.Android.cs) and any other Android-specific configurations or code.
    • iOS: Contains the iOS-specific entry point (Main.iOS.cs).
    • MacCatalyst: Contains the MacCatalyst-specific entry point (Main.maccatalyst.cs).
    • BrowserWasm: Contains the Browser WASM specific configurations or code.
    • Desktop: Contains the Desktop specific configurations or code.
  • Services: Contains service classes implementing business logic, data access, etc. This folder often includes subfolders like:
  • Strings: the purpose of this folder is to store the localized string resources for the application so it can be translated to multiple languages.
  • Styles: this folder contains the styles or color configuration for the app.

Build Configuration Files

Several build configuration files in the root of the solution control the build process:

  • Directory.Build.props: Contains global MSBuild properties applied to all projects.
  • Directory.Build.targets: Contains global MSBuild targets for all projects.
  • Directory.Packages.props: Centralizes package versions for dependency management.
  • global.json: Specifies the Uno.SDK version and other .NET SDK configurations.

The Power of Uno.Sdk

One of the most important aspects of modern Uno Platform development is the Uno.Sdk, which significantly simplifies the development process.

What is Uno.Sdk?

Uno.Sdk is a specialized MSBuild SDK that streamlines Uno Platform development by providing:

  1. A cross-platform development experience that simplifies targeting multiple platforms from a single project
  2. Automatic management of platform-specific dependencies and configurations
  3. A simplified build process that handles the complexity of building for different target platforms
  4. Feature-based configuration that enables adding functionality through the UnoFeatures property

In your project file, you’ll see <Project Sdk="Uno.Sdk"> at the top, indicating that this project uses the Uno SDK rather than the standard .NET SDK.

Key Components of the Project File

TargetFrameworks

<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst;net9.0-windows10.0.26100;net9.0-browserwasm;net9.0-desktop</TargetFrameworks>

This line specifies that your application targets:

  • Android
  • iOS
  • macOS (via Mac Catalyst)
  • Windows (Windows 10/11 with SDK version 10.0.26100)
  • WebAssembly (for browser-based applications)
  • Desktop (for cross-platform desktop applications)

All of these targets use .NET 9 as the base framework.

Single Project Configuration

<OutputType>Exe</OutputType>
<UnoSingleProject>true</UnoSingleProject>
  • OutputType: Specifies this project builds an executable application
  • UnoSingleProject: Enables Uno’s single-project approach, allowing you to maintain one codebase for all platforms

Application Metadata

<ApplicationTitle>UnoAnatomy</ApplicationTitle>
<ApplicationId>com.companyname.UnoAnatomy</ApplicationId>
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<ApplicationPublisher>joche</ApplicationPublisher>
<Description>UnoAnatomy powered by Uno Platform.</Description>

These properties define your app’s identity and metadata used in app stores and installation packages.

UnoFeatures

The most powerful aspect of Uno.Sdk is the UnoFeatures property:

<UnoFeatures>
  Material;
  Dsp;
  Hosting;
  Toolkit;
  Logging;
  Mvvm;
  Configuration;
  Http;
  Serialization;
  Localization;
  Navigation;
  ThemeService;
</UnoFeatures>

This automatically adds relevant NuGet packages for each listed feature:

  • Material: Material Design UI components
  • Dsp: Digital Signal Processing capabilities
  • Hosting: Dependency injection and host builder pattern
  • Toolkit: Community Toolkit components
  • Logging: Logging infrastructure
  • Mvvm: Model-View-ViewModel pattern implementation
  • Configuration: Application configuration framework
  • Http: HTTP client capabilities
  • Serialization: Data serialization/deserialization
  • Localization: Multi-language support
  • Navigation: Navigation services
  • ThemeService: Dynamic theme support

The UnoFeatures property eliminates the need to manually add numerous NuGet packages and ensures compatibility between components.

Benefits of the Uno Platform Structure

This structured approach to cross-platform development offers several advantages:

  1. Code Sharing: Most code is shared across platforms, reducing duplication and maintenance overhead.
  2. Platform-Specific Adaptation: When needed, the structure allows for platform-specific implementations.
  3. Simplified Dependencies: The Uno.Sdk handles complex dependency management behind the scenes.
  4. Consistent Experience: Ensures a consistent development experience across all target platforms.
  5. Future-Proofing: The architecture makes it easier to add support for new platforms in the future.

Conclusion

Understanding the anatomy of an Uno Platform solution is crucial for effective cross-platform development. The combination of shared code, platform-specific heads, and the powerful Uno.Sdk creates a development experience that makes it much easier to build and maintain applications across multiple platforms from a single codebase.

By leveraging this structure and the features provided by the Uno Platform, you can focus on building your application’s functionality rather than dealing with the complexities of cross-platform development.

In my next article in this series, we’ll dive deeper into the practical aspects of developing with Uno Platform, exploring how to leverage these structural components to build robust cross-platform applications.

 

Related articles

Getting Started with Uno Platform: First Steps and Configuration Choices | Joche Ojeda

My Adventures Picking a UI Framework: Why I Chose Uno Platform | Joche Ojeda

Exploring the Uno Platform: Handling Unsafe Code in Multi-Target Applications | Joche Ojeda

About Us

YouTube

https://www.youtube.com/c/JocheOjedaXAFXAMARINC

Our sites

Let’s discuss your XAF

This call/zoom will give you the opportunity to define the roadblocks in your current XAF solution. We can talk about performance, deployment or custom implementations. Together we will review you pain points and leave you with recommendations to get your app back in track

https://calendly.com/bitframeworks/bitframeworks-free-xaf-support-hour

Our free A.I courses on Udemy

Getting Started with Uno Platform: First Steps and Configuration Choices

Getting Started with Uno Platform: First Steps and Configuration Choices

For the past two weeks, I’ve been experimenting with the Uno Platform in two ways: creating small prototypes to explore features I’m curious about and downloading example applications from the Uno Gallery. In this article, I’ll explain the first steps you need to take when creating an Uno Platform application, the decisions you’ll face, and what I’ve found useful so far in my journey.

Step 1: Create a New Project

I’m using Visual Studio 2022, though the extensions and templates work well with previous versions too. I have both studio versions installed, and Uno Platform works well in both.

Step 2: Project Setup

After naming your project, it’s important to select “Place solution and project in the same directory” because of the solution layout requirements. You need the directory properties file to move forward. I’ll talk more about the solution structure in a future post, but for now, know that without checking this option, you won’t be able to proceed properly.

Step 3: The Configuration Wizard

The Uno Platform team has created a comprehensive wizard that guides you through various configuration options. It might seem overwhelming at first, but it’s better to have this guided approach where you can make one decision at a time.

Your first decision is which target framework to use. They recommend .NET 9, which I like, but in my test project, I’m working with .NET 8 because I’m primarily focused on WebAssembly output. Uno offers multi-threading in Web Assembly with .NET 8, which is why I chose it, but for new projects, .NET 9 is likely the better choice.

Step 4: Target Platforms

Next, you need to select which platforms you want to target. I always select all of them because the most beautiful aspect of the Uno Platform is true multi-targeting with a single codebase.

In the past (during the Xamarin era), you needed multiple projects with a complex directory structure. With Uno, it’s actually a single unified project, creating a clean solution layout. So while you can select just WebAssembly if that’s your only focus, I think you get the most out of Uno by multi-targeting.

Step 5: Presentation Pattern

The next question is which presentation pattern you want to use. I would suggest MVUX, though I still have some doubts as I haven’t tried MVVM with Uno yet. MVVM is the more common pattern that most programmers understand, while MVUX is the new approach.

One challenge is that when you check the official Uno sample repository, the examples come in every presentation pattern flavor. Sometimes you’ll find a solution for your task in one pattern but not another, so you may need to translate between them. You’ll likely find more examples using MVVM.

Step 6: Markup Language

For markup, I recommend selecting XAML. In my first project, I tried using C# markup, which worked well until I reached some roadblocks I couldn’t overcome. I didn’t want to get stuck trying to solve one specific layout issue, so I switched. For beginners, I suggest starting with XAML.

Step 7: Theming

For theming, you’ll need to select a UI theme. I don’t have a strong preference here and typically stick with the defaults: using Material Design, the theme service, and importing Uno DSP.

Step 8: Extensions

When selecting extensions to include, I recommend choosing almost all of them as they’re useful for modern application development. The only thing you might want to customize is the logging type (Console, Debug, or Serilog), depending on your previous experience. Generally, most applications will benefit from all the extensions offered.

Step 9: Features

Next, you’ll select which features to include in your application. For my tests, I include everything except the MAUI embedding and the media element. Most features can be useful, and I’ll show in a future post how to set them up when discussing the solution structure.

Step 10: Authentication

You can select “None” for authentication if you’re building test projects, but I chose “Custom” because I wanted to see how it works. In my case, I’m authenticating against DevExpress XAF REST API, but I’m also interested in connecting my test project to Azure B2C.

Step 11: Application ID

Next, you’ll need to provide an application ID. While I haven’t fully explored the purpose of this ID yet, I believe it’s needed when publishing applications to app stores like Google Play and the Apple App Store.

Step 12: Testing

I’m a big fan of testing, particularly integration tests. While unit tests are essential when developing components, for business applications, integration tests that verify the flow are often sufficient.

Uno also offers UI testing capabilities, which I haven’t tried yet but am looking forward to exploring. In platform UI development, there aren’t many choices for UI testing, so having something built-in is fantastic.

Testing might seem like a waste of time initially, but once you have tests in place, you’ll save time in the future. With each iteration or new release, you can run all your tests to ensure everything works correctly. The time invested in creating tests upfront pays off during maintenance and updates.

Step 13: CI Pipelines

The final step is about CI pipelines. If you’re building a test application, you don’t need to select anything. For production applications, you can choose Azure Pipelines or GitHub Actions based on your preferences. In my case, I’m not involved with CI pipeline configuration at my workplace, so I have limited experience in this area.

Conclusion

If you’ve made it this far, congratulations! You should now have a shiny new Uno Platform application in your IDE.

This post only covers the initial setup choices when creating a new Uno application. Your development path will differ based on the selections you’ve made, which can significantly impact how you write your code. Choose wisely and experiment with different combinations to see what works best for your needs.

During my learning journey with the Uno Platform, I’ve tried various settings—some worked well, others didn’t, but most will function if you understand what you’re doing. I’m still learning and taking a hands-on approach, relying on trial and error, occasional documentation checks, and GitHub Copilot assistance.

Thanks for reading and see you in the next post!

About Us

YouTube

https://www.youtube.com/c/JocheOjedaXAFXAMARINC

Our sites

Let’s discuss your XAF

https://www.udemy.com/course/microsoft-ai-extensions/

Our free A.I courses on Udemy