7.2 KiB
Fixiy — Agent Guide
Project Overview
Fixiy is a .NET MAUI Blazor Hybrid app that shares its entire UI with a Blazor Server Web App via a Razor Class Library (RCL). All pages and components live in Fixiy.Shared and are consumed by both host projects without modification.
- App ID:
it.integry.fixiy - Solution:
Fixiy.sln - SDK: .NET 10 (
global.json—rollForward: latestMajor) - NuGet source: Private feed — see
NuGet.Config(https://nuget.studioml.it/repository/nuget-group/index.json) - Platforms: Android 26+, iOS 15+, Web (Blazor Server)
Repository Structure
Fixiy.sln
├── Fixiy.Maui/ # .NET MAUI Blazor Hybrid host (Android + iOS)
│ ├── MauiProgram.cs # DI root — registers MAUI services + IntegryApiClient
│ ├── Services/FormFactor.cs # MAUI implementation of IFormFactor (uses DeviceInfo)
│ ├── Platforms/ # Platform-specific entry points (Android, iOS, …)
│ └── Resources/ # App icons, splash, fonts, images
├── Fixiy.Shared/ # Razor Class Library — all shared UI
│ ├── Components/
│ │ ├── Layout/ # MainLayout.razor, NavBar.razor, NavMenu.razor
│ │ ├── Pages/ # Routable pages (e.g., Home.razor)
│ │ └── SingleElements/ # Reusable components (e.g., NoDataAvailable.razor)
│ ├── Interfaces/IFormFactor.cs # Platform abstraction interface
│ ├── InteractiveRenderSettings.cs # Shared render mode constants (nulled in MAUI)
│ └── _Imports.razor # Global using directives for shared components
└── Fixiy.Web/ # Blazor Server Web App host
├── Program.cs # DI root — registers web services + IntegryApiClient
└── Services/FormFactor.cs # Web implementation of IFormFactor
Tech Stack
| Layer | Technology |
|---|---|
| Mobile host | .NET MAUI Blazor Hybrid — net10.0-android, net10.0-ios |
| Web host | Blazor Server (ASP.NET Core, net10.0) |
| Shared UI | Razor Class Library (Fixiy.Shared, net10.0) |
| Client SDK | IntegryApiClient — MAUI / Core / Blazor variants (private NuGet) |
| Fonts | OpenSans via MAUI font registration |
Build & Run
Prerequisites: .NET SDK 10, MAUI workload (dotnet workload install maui) for mobile builds.
# Restore (requires private NuGet credentials — see NuGet.Config)
dotnet restore Fixiy.sln
# Run Blazor Web App (no platform SDK required)
dotnet run --project Fixiy.Web/Fixiy.Web.csproj
# Build MAUI for Android (requires MAUI workload)
dotnet build Fixiy.Maui/Fixiy.Maui.csproj -f net10.0-android
# Build MAUI for iOS (requires macOS + Xcode)
dotnet build Fixiy.Maui/Fixiy.Maui.csproj -f net10.0-ios
Key Patterns and Conventions
1. InteractiveRenderSettings pattern
Fixiy.Shared/InteractiveRenderSettings.cs exposes static IComponentRenderMode? properties (InteractiveServer, InteractiveAuto, InteractiveWebAssembly). In Fixiy.Web these remain set to real render modes. In Fixiy.Maui, MauiProgram.ConfigureBlazorHybridRenderModes() sets all three to null — MAUI Blazor Hybrid does not support server or WASM render modes.
Always use the property, not the constant, in shared components:
@* Wrong — hard-coded constant, crashes in MAUI *@
@rendermode="RenderMode.InteractiveServer"
@* Correct — resolves to null in MAUI, InteractiveServer in Web *@
@rendermode="@InteractiveServer"
2. IFormFactor platform abstraction
IFormFactor (in Fixiy.Shared/Interfaces/) provides GetFormFactor() and GetPlatform(). Each host project provides its own implementation registered in DI. Inject IFormFactor in shared components; never call DeviceInfo or other MAUI APIs from Fixiy.Shared.
3. IntegryApiClient registration
Both DI roots register IntegryApiClient with the same appToken and useLoginAzienda: true.
- MAUI:
.UseIntegry(appToken, useLoginAzienda: true)onMauiAppBuilder - Web:
builder.Services.UseIntegry(appToken, useLoginAzienda: true)
The app token must match across both registrations. It is currently declared as a const in MauiProgram.cs and a const string in Fixiy.Web/Program.cs.
4. Adding a new page
- Create
Fixiy.Shared/Components/Pages/YourPage.razorwith@page "/your-route" - No extra registration required —
Routes.razordiscovers pages via assembly scanning - Add a navigation entry to
Fixiy.Shared/Components/Layout/NavMenu.razorif user-accessible
5. Adding a platform-specific service
- Define the interface in
Fixiy.Shared/Interfaces/IYourService.cs - Implement in
Fixiy.Maui/Services/YourService.cs(may use MAUI APIs) - Implement in
Fixiy.Web/Services/YourService.cs(BCL only) - Register in
Fixiy.Maui/MauiProgram.csasAddSingleton<IYourService, YourService>() - Register in
Fixiy.Web/Program.csasAddScoped<IYourService, YourService>()
Maintenance Matrix
| When you change… | Also update… |
|---|---|
Fixiy.Shared/Interfaces/IFormFactor.cs |
Fixiy.Maui/Services/FormFactor.cs and Fixiy.Web/Services/FormFactor.cs |
Any interface in Fixiy.Shared/Interfaces/ |
Both platform Services/ implementations + both DI roots |
InteractiveRenderSettings.cs (add/remove property) |
MauiProgram.ConfigureBlazorHybridRenderModes() — must null all new properties |
Fixiy.Shared/_Imports.razor |
Verify imports are valid in both MAUI and Web (no platform-only namespaces) |
| IntegryApiClient package version | Update in all three .csproj files consistently |
| App token | Update in both Fixiy.Maui/MauiProgram.cs and Fixiy.Web/Program.cs |
Fixiy.Shared/Components/Layout/NavMenu.razor |
Review navigation works on both platforms |
CI/CD
No CI pipeline is currently configured. The project uses a private NuGet feed (NuGet.Config). For CI builds:
- Set
NUGET_USERNAMEandNUGET_PASSWORD(or PAT) as CI secrets - Build only
Fixiy.Webin standard CI; MAUI builds require platform-specific agents with MAUI workloads - See
.github/workflows/copilot-setup-steps.ymlfor environment setup reference
Common Pitfalls
- Render mode constants in shared code: Use
@InteractiveServer(property fromInteractiveRenderSettings) neverRenderMode.InteractiveServer. The MAUI host nulls these viaConfigureBlazorHybridRenderModes(). - MAUI APIs in Fixiy.Shared:
DeviceInfo,FileSystem,Connectivity, and otherMicrosoft.Maui.*APIs are not available in the RCL. Define a newIFormFactor-style interface instead. - Private NuGet feed: All
dotnet restorecalls require credentials. In CI, add the source credentials via environment secrets — theNuGet.Config<clear/>directive removes all default sources. - MAUI workload for builds:
dotnet workload install mauiis required before buildingFixiy.Maui. Standard CI runners (Ubuntu) don't have it by default. - Service lifetimes: MAUI registers platform services as
Singleton(long-lived app); Web registers them asScoped(per request). Interfaces must not assume a specific lifetime.