Introduction
Why Realm with .NET 9 & Blazor?
Realm is a modern, fast, mobile-first object database from MongoDB. It integrates seamlessly with C#, supports reactive data binding, offline sync, and is much simpler than SQLite when dealing with complex models or syncing data. Paired with .NET 9 and Blazor (WebAssembly or Server), you get:
- Strong typing & shared models across client/server
- Reactive UI updates out of the box
- Rich querying with LINQ
- Offline-first support with Realm Sync potential
🧩 Sample Use Case: Personal Task Manager
We’ll build a simple task manager:
- Database: task storage and queries
- Business logic: add, complete, delete tasks
- UI: interactive Blazor components
1. Database Models & Realm Setup
Install Realm SDK
dotnet add package MongoDB.Realm
Define the data model
using Realms;
public class TaskItem : RealmObject
{
[PrimaryKey]
public string Id { get; set; } = Guid.NewGuid().ToString();
public string Title { get; set; } = "";
public bool IsDone { get; set; } = false;
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}
Opening Realm
var config = new RealmConfiguration("tasks.realm");
var realm = Realm.GetInstance(config);
This creates a local file tasks.realm for persistent storage and reactive syncing.
2. Business Logic: Realm Service
Wrap Realm operations in a service for DI and separation of concerns.
public class TaskService : IDisposable
{
private readonly Realm _realm;
public IRealmCollection<TaskItem> Tasks { get; }
public TaskService()
{
_realm = Realm.GetInstance(new RealmConfiguration("tasks.realm"));
Tasks = _realm.All<TaskItem>().AsRealmCollection();
}
public void AddTask(string title)
{
_realm.Write(() =>
{
_realm.Add(new TaskItem { Title = title });
});
}
public void ToggleDone(TaskItem task)
{
_realm.Write(() =>
{
task.IsDone = !task.IsDone;
});
}
public void DeleteTask(TaskItem task)
{
_realm.Write(() =>
{
_realm.Remove(task);
});
}
public void Dispose() => _realm.Dispose();
}
Why this helps: C# type safety, automatic UI notifications via AsRealmCollection, and no JSON/ORM mapping hassle.
3. UI with Blazor
Setup in Program.cs
builder.Services.AddSingleton<TaskService>();
await builder.Build().RunAsync();
Task List Component: Pages/Tasks.razor
@page "/tasks"
@inject TaskService TaskSvc
<h3>Tasks</h3>
<input @bind="newTitle" @onkeydown="@OnEnter" placeholder="New task..." />
<button @onclick="Add">Add</button>
<ul>
@foreach (var task in TaskSvc.Tasks)
{
<li>
<input type="checkbox" checked="@task.IsDone" @onchange="@(() => Toggle(task))" />
<span class="@(task.IsDone ? "done" : "")">@task.Title</span>
<button @onclick="() => Delete(task)">🗑️</button>
</li>
}
</ul>
@code {
private string newTitle = "";
void Add()
{
if (!string.IsNullOrWhiteSpace(newTitle))
TaskSvc.AddTask(newTitle.Trim());
newTitle = "";
}
void OnEnter(KeyboardEventArgs e)
{
if (e.Key == "Enter") Add();
}
void Toggle(TaskItem t) => TaskSvc.ToggleDone(t);
void Delete(TaskItem t) => TaskSvc.DeleteTask(t);
}
.done {
text-decoration: line-through;
color: gray;
}
Nuances of Blazor + Realm
- Reactive UI:
TaskSvc.Tasksupdates UI automatically when data changes - Shared logic: same
TaskServiceacross server & client - Pure C# stack: no need for JavaScript on data operations (learn.microsoft.com, dworthen.github.io, dotnettutorials.net)
4. (Optional) Sync with MongoDB Realm Server
var config = new AppConfiguration("YOUR_REALM_APP_ID");
var app = App.Create(config);
var user = await app.LogInAsync(Credentials.EmailPassword(email, pw));
var syncConfig = new SyncConfiguration("tasksPartition", user);
var realm = Realm.GetInstance(syncConfig);
This enables cross-device sync, offline-first behavior, and real-time updates.
🔍 Benefits Summary
| Feature | Benefit |
|---|---|
| C# objects & LINQ | Type-safe, compile-time queries |
| Realm UI binding | Automatic reloading with minimal wiring |
| Offline-first + sync-ready | Local storage plus optional real-time sync |
| Unified across .NET | Same service in Blazor Server & WebAssembly |
🏁 Conclusion
We’ve built a simple yet powerful task manager with:
- Realm as the local (optionally syncable) database: clean, reactive, C#-typed
- TaskService: encapsulates all data operations
- Blazor UI: instantly responds to data changes without manual refreshes
The result? A full-stack C# app—from persistence to user interface—with clean architecture, real-time interactivity, and offline resilience, all using .NET 9 and Blazor.
Views: 11
