# Online/Offline Data-Capable Cross-Platform Apps with MongoDB Atlas, Atlas Device SDKs and .NET MAUI

In a world of always-on, always-connected devices, it is more important than ever that apps function in a way that gives a user a good experience. But as well as the users, developers matter too. We want to be able to feel productive and focus on delivery and innovation, not solving common problems.

In this article, we will look at how you can mix .NET MAUI with MongoDB’s Atlas App Services, including the Atlas Device SDKs mobile database, for online/offline-capable apps without the pain of coding for network handling and errors.

## What are Atlas Device SDKs?
Atlas Device SDKs, formerly Realm is an alternative to SQLite that takes advantage of MongoDB’s document data model. It is a mobile-first database that has been designed for modern data-driven applications. Although the focus of this article is the mobile side of Atlas Device SDK, it actually also supports the building of web, desktop, and IoT apps.

Atlas Device SDKs have some great features that save a lot of time as a developer. It uses an object-oriented data model so you can work directly with the native objects without needing any Object Relational Mappers (ORMs) or Data Access Objects (DAO). This also means it is simple to start working with and scales well.

Plus, Atlas Device SDKs are part of the Atlas App Services suite of products that you get access to via the SDK. This means that Realm also has automatic access to a built-in, device-to-cloud sync feature. It uses a local database stored on the device to allow for always-on functionality. MongoDB also has Atlas, a document database as a service in the cloud, offering many benefits such as resilience, security, and scaling. The great thing about device sync with App Services is it links to a cloud-hosted MongoDB Atlas cluster, automatically taking care of syncing between them, including in the event of changes in network connectivity. By taking advantage of Atlas, you can share data between multiple devices, users, and the back ends using the same database cluster. 

## Can you use Atlas Device SDKs with .NET MAUI?
In short, yes! There is a .NET SDK available that supports .NET, MAUI (including Desktop), Universal Windows Platform (UWP), and even Unity.

In fact, Maddy Montaquila (Senior PM for MAUI at Microsoft) and I got talking about fun project ideas and came up with HouseMovingAssistant, an app built using .NET MAUI and Atlas Device SDKs, for tracking tasks related to moving house. 

It takes advantage of all the great features of Atlas Device SDKs and App Services, including device sync, data partitioning based on the logged-in user, and authentication to handle the logging in and out.

It even uses another MongoDB feature, Charts, which allows for great visualizations of data in your Atlas cluster, without having to use any complex graphing libraries!

## Code ##
The actual code for working with Atlas Device SDKs is very simple and straightforward. This article isn't a full tutorial, but we will use code snippets to show how simple it is. If you want to see the full code for the application, you can find it on GitHub.

> Note that despite the product update name, the Realm name is still used in the library name and code for now so you will see references to Realm throughout the next sections.

### Initialization
```csharp
RealmApp = Realms.Sync.App.Create(AppConfig.RealmAppId);
```
This code creates your Realm Sync App and lives inside of App.Xaml.cs.

```csharp
PartitionSyncConfiguration config = new PartitionSyncConfiguration($"{App.RealmApp.CurrentUser.Id}", App.RealmApp.CurrentUser);           return Realm.GetInstance(config);
```
The code above is part of an initialization method and uses the RealmApp from earlier to create the connection to your app inside of App Services. This gives you access to features such as authentication (and more), as well as your Atlas data.

### Log in/create an account ###
Working with authentication is equally as simple. Creating an account is as easy as picking an authentication type and passing the required credentials.

The most simple way is email and password auth using details entered in a form in your mobile app.

```csharp
await App.RealmApp.EmailPasswordAuth.RegisterUserAsync(EmailText, PasswordText);
```

Logging in, too, is one call.

```csharp
var user = await App.RealmApp.LogInAsync(Credentials.EmailPassword(EmailText, PasswordText));
```

Of course, you can add conditional handling around this, such as checking if there is already a user object available and combining that with navigation built into MAUI, such as Shell, to simply skip logging in if the user is already logged in:

```csharp
if (user != null)
                {
                    await AppShell.Current.GoToAsync("///Main");
                }
```

### Model
As mentioned earlier in the article, Atlas Device SDKs can work with simple C# objects with properties, and use those as fields in your document, handling mapping between object and document.

One example of this is the MovingTask object, which represents a moving task. Below is a snippet of part of the MovingTask.cs model object.

```csharp
PrimaryKey]
        [MapTo("_id")]
        public ObjectId Id { get; set; } = ObjectId.GenerateNewId();

        [MapTo("owner")]
        public string Owner { get; set; }

        [MapTo("name")]
        [Required]
        public string Name { get; set; }

        [MapTo("_partition")]
        [Required]
        public string Partition { get; set; }

        [MapTo("status")]
        [Required]
        public string Status { get; set; }

        [MapTo("createdAt")]        
        public DateTimeOffset CreatedAt { get; set; }

```

It uses standard properties, with some additional attributes from the [MongoDB driver, which mark fields as required and also say what fields they map to in the document. This is great for handling different upper and lower case naming conventions, differing data types, or even if you wanted to use a totally different name in your documents versus your code, for any reason.

You will notice that the last property uses the DateTimeOffset data type, which is part of C#. This isn’t available as a data type in a MongoDB document, but the driver is able to handle converting this to and from a supported type without requiring any manual code, which is super powerful.

## Do Atlas Device SDKs support MVVM?
Absolutely. It fully supports INotifyPropertyChanged events, meaning you don’t have to worry about whether the data is up to date. You can trust that it is. This support for events means that you don’t need to have an extra layer between your viewmodel and your database if you don’t want to.

As of Realm 10.18.0 (as it was known at the time), there is even support for Source Generators, making it even easier to work with Atlas Device SDKs and MVVM applications.

HouseMovingAssistant fully takes advantage of Source Generators. In fact, the MovingTask model that we saw earlier implements IRealmObject, which is what brings in source generation to your models.

The list of moving tasks visible on the page uses a standard IEnumerable type, fully supported by CollectionView in MAUI.

```csharp
ObservableProperty]
        IEnumerable movingTasks;
```
 Populating that list of tasks is then easy thanks to LINQ support.

```chsarp
MovingTasks = realm.All().OrderBy(task => task.CreatedAt);
```
## What else should I know?
There are a couple of extra things to know about working with Atlas Device SDKs from your .NET MAUI applications.

### Services
Although as discussed above, you can easily and safely talk directly to the database (via the SDK) from your viewmodel, it is good practice to have an additional service class. This could be in a different/shared project that is used by other applications that want to talk to Atlas, or within your application for an added abstraction.

In HouseMovingAssistant, there is a RealmDatabaseService.cs class which provides a method for fetching the Realm instance. This is because you only want one instance of your Realm at a time, so it is better to have this as a public method in the service.

```csharp
public static Realm GetRealm()
        {
            PartitionSyncConfiguration config = new PartitionSyncConfiguration($"{App.RealmApp.CurrentUser.Id}", App.RealmApp.CurrentUser);
            return Realm.GetInstance(config);
        }

```
### Transactions
Because of the way Atlas Device SDKs work under the hood, any kind of operation to it — be it read, create, update, or delete — is done inside what is called a write transaction. The use of transactions means that actions are grouped together as one and if one of those fails, the whole thing fails. 

Carrying out a transaction inside the Realm .NET SDK is super easy. We use it in HouseMovingAssistant for many features, including creating a new task, updating an existing task, or deleting one.

```csharp
var task =
                    new MovingTask
                    {
                        Name = MovingTaskEntryText,
                        Partition = App.RealmApp.CurrentUser.Id,
                        Status = MovingTask.TaskStatus.Open.ToString(),
                        Owner = App.RealmApp.CurrentUser.Profile.Email,
                        CreatedAt = DateTimeOffset.UtcNow
                    };

                realm.Write(() =>
                {
                    realm.Add(task);
                });
```
The code above creates a task using the model we saw earlier and then inside a write transaction, adds that object to the Realm database, which will in turn update the Atlas cluster it is connected to. This is a great example of how you don’t need an ORM, as we create an object from our model class and can directly add it, without needing to do anything extra.
## Summary
In this article, we have gone on a whistle stop tour of .NET MAUI with Atlas Device SDKs (formerly Realm), and how you can quickly get up and running with a data capable application, with online/offline support and no need for an ORM.

There is so much more you can do with Atlas Device SDKs, MongoDB Atlas, and the App Services platform. A great article to read next is on [advanced data modelling with Realm and .NET by the lead engineer for the Atlas Device SDKs .NET team, Nikola Irinchev.

You can get started today by signing up to an Atlas account and discovering the world of Realm, Atlas and Atlas App Services!