CASE STUDY: ENTERPRISE MAUI

Taking .NET MAUI to the Edge

A multi-client, real-time consultancy platform. We architected an "Uber-style" matching engine using RabbitMQ, SignalR, and ReactiveUI to deliver millisecond latency across mobile networks.

2
Native
Apps
10k+
Real-time
Events
📱
API
🐇
🍃

The Stack

A vertical slice of modern .NET engineering.

📱

Presentation (.NET MAUI)

Native-like performance with Reactive architectures.

  • MVVM + ReactiveUI: Observable state management.
  • DynamicData: Reactive collections for chat lists.
  • Offline-First: Local SQLite + JSON caching.
  • Resilience: Automatic SignalR reconnection.
☁️

Application API

  • ASP.NET Core 8 Web API
  • SignalR Hubs (Real-time)
  • MediatR Orchestration
  • FastEndpoints Implementation
🏗️

Infrastructure

  • RabbitMQ: Event Bus for decoupling.
  • Hangfire: Background job processing.
  • EF Core: SQL Server persistence.
  • Redis: Distributed Caching.
🧠

Shared Kernel (DDD)

The brain of the operation. Pure C# logic.

  • Specifications: Encapsulated query logic (e.g., ConsultantsWithNoActiveConversationsSpec).
  • Aggregates: Transactional boundaries for `Conversation` and `Customer`.
  • Value Objects: Immutable types for critical business data.

The "Uber-Match" Workflow

How we connect a Customer to a Consultant in milliseconds.

T+0ms
Customer Initiates Chat MAUI

User taps "Preguntar". The app stores the message locally (Optimistic UI) and pushes to SignalR.

T+50ms
API Routing SignalR

Hub receives `CustomerInitiatedChat`. Does NOT block. Wraps payload and pushes to RabbitMQ `customer_first_auto_chat`.

T+100ms
Async Processing RabbitMQ

Background Service consumes message. Triggers MediatR Command. Uses ConsultantEligibilitySpec to find available agents.

T+200ms
Consultant Notification SignalR

Server broadcasts `HelloConsultantIArrived` to targeted Consultant Groups. Consultants see "New Request" pop up.

T+1500ms
Consultant Claims MAUI

Consultant taps "Accept". HTTP POST claims the `UnansweredConversation`. EF Core creates the Aggregate.

T+1600ms
Handshake Complete Success

System upgrades connection to Direct Chat. History synced to Mongo/GridFS.

// ChatPageViewModel.cs

public ChatPageViewModel(...)
{
  // Reactive Command
  SendCommand = ReactiveCommand
    .CreateFromTask(SendMessage);

  // SignalR Subscription
  _hub.OnMessageReceived
    .ObserveOn(RxApp.MainThread)
    .Subscribe(msg => {
      Messages.Add(msg);
      ScrollToBottom();
    });
}

private async Task SendMessage()
{
  // Optimistic UI Update
  Messages.Add(new Msg("..."));
  await _hub.SendAsync("Chat", txt);
}

Client-Side Engineering

We didn't just wrap a website. We built a resilient, reactive native application.

ReactiveUI Integration

We use SourceList and ObservableAsPropertyHelper to manage state. The UI is a pure function of the data stream, eliminating synchronization bugs.

Offline Resilience

Messages are queued in a local ConcurrentQueue if the network drops. A background Rx Timer retries sending transparently when connectivity is restored.

Polyglot Caching

Chat history is cached on disk (JSON) for instant load, while Redis handles ephemeral presence data on the server.

Polyglot Persistence

Using the right tool for the right job.

🐘

SQL Server

Core relational data. Customers, Consultants, Financial Transactions.

🍃

MongoDB

Chat logs and Audit trails. Flexible schema for message metadata.

Redis

Real-time Presence. "Who is online?" and distributed SignalR backplane.

📦

GridFS

Binary storage. Efficient handling of images and PDF attachments.