In the first two lessons of this course, the Kladde became an app: it has pages for contacts and for today’s appointments, connected by Shell, with fixed sample data in the code. That’s fine for a prototype. As soon as data comes from a web API, a form has rules and someone needs to check a change, the code behind the pages becomes a problem: you can only try it out with a running emulator. This lesson separates the logic from the user interface until you can check it with dotnet test.

The scope of this lesson:

Part What you get
Pattern Model, view and view model, and what the binding in between does
Toolkit ObservableObject, [ObservableProperty], [RelayCommand]
Wiring Dependency injection in MauiProgram, navigation behind an interface
Testing a project Kladde.App.Logic without MAUI and a test project for it

Where the Kladde stands

The course assumes what lesson W2.1.2 built. To be safe, here is the picture this lesson starts from:

  • There is the project src/Kladde.App (the MAUI app, namespace Kladde.App), which starts on the Android emulator and on Windows. It is not in Kladde.slnx yet; this lesson decides how it gets there.
  • The folder Models holds the records ContactResponse (Id, Name, Email, Company, Tags) and AppointmentResponse (Title, Start, End, ContactIds) and the static class SampleData with the fixed contacts and today’s appointments.
  • The folder Pages holds ContactsPage, ContactDetailPage and AppointmentsPage. Shell knows the route contactdetails for the detail page, which gets its contact from a dictionary through IQueryAttributable.
  • The pages have code-behind that fills the lists from SampleData.

Your pages and classes may be named differently. Keep your names and apply the steps. New in this lesson is the page NewAppointmentPage in the namespace Kladde.App.Pages.