Skip to content

Instructions 05 MAUI

Sebastian Szvetecz edited this page Sep 28, 2023 · 4 revisions

Part 5 - .NET MAUI Part 1

Create a .NET MAUI application that can run on Windows, Android, iOS, and macOS. A library is created to send requests to the API service. This library can be used from all .NET applictions. A view-models library is created to offer the view-models used by the application. This library can be used by all XAML-based applications.

Create the MAUI Application

  1. Create a .NET MAUI application for multiple platforms.
  2. Add a reference to the NuGet packages Microsoft.Extensions.Http, Microsoft.Extensions.Configuration.Json
  3. Create two libraries for viewmodels and client-services libraries, and reference these as well: CodeBreaker.ViewModels and CodeBreaker.ClientServices
  4. With the client-services library, reference the shared library created before.
  5. Support both .NET 7 and .NET 8 with these libraries.

A Client library calling the REST API

If you are not interested in developing the client library on your own, because you want to focus on MAUI or you simply have not enough time, you can use our NuGet package CNinnovation.Codebreaker.GamesClient.

Bear in mind, that you still need to register the gamesclient in the DI container.

If you want to use our hosted backend you can define https://codebreaker-gamesapi-3.purplebush-9a246700.westeurope.azurecontainerapps.io as ApiBase in your configuration.

  1. Open the library CodeBreaker.ClientServices
  2. Reference the shared library created before, and add the NuGet package for logging, Microsoft.Extensions.Logging.Abstractions.
  3. Create the interfaces IGameClient
  4. Create the GameClient implementation - inject the HttpClient and use it to call the REST API using extension methods such as GetFromJsonAsync and PostAsJsonAsync

Build the project, create a NuGet package.

Configure the .NET MAUI Application

  1. Open the .NET MAUI application
  2. Add appsettings.json to the .NET MAUI application, and configure it as a MauiAsset, copy always
  3. Configure the AppBase setting with the configuration file
  4. Add the MAUI configuration to read the appsettings.json file
  5. Configure the HttpClient with MauiProgram.cs

Source Code Client Library

Contracts

public interface IGameClient
{
    Task<CreateMoveResponse> SetMoveAsync(Guid gameId, params string[] colorNames);

    Task<CreateGameResponse> StartGameAsync(string username);
}

Implementation

Implement the GameClient class, which implements both interfaces.

public class GameClient : IGameClient
{
    private readonly HttpClient _httpClient;

    private readonly ILogger _logger;

    public GameClient(HttpClient httpClient, ILogger<GameClient> logger)
    {
        _httpClient = httpClient;
        _logger = logger;
        _logger.LogInformation("Injected HttpClient with base address {uri} into GameClient", _httpClient.BaseAddress);
    }

    public async Task<CreateGameResponse> StartGameAsync(string username)
    {
        CreateGameRequest request = new(username);
        HttpResponseMessage responseMessage = await _httpClient.PostAsJsonAsync("/games", request);
        responseMessage.EnsureSuccessStatusCode();
        return await responseMessage.Content.ReadFromJsonAsync<CreateGameResponse>();
    }

    public async Task<CreateMoveResponse> SetMoveAsync(Guid gameId, params string[] colorNames)
    {
        CreateMoveRequest request = new(colorNames.ToList());
        HttpResponseMessage responseMessage = await _httpClient.PostAsJsonAsync($"/games/{gameId}/moves", request);
        responseMessage.EnsureSuccessStatusCode();
        return await responseMessage.Content.ReadFromJsonAsync<CreateMoveResponse>();
    }
}

MAUI Application

Configure the HttpClient with the DI container and configuration

builder.Configuration.AddJsonStream(FileSystem.OpenAppPackageFileAsync("appsettings.json").Result);
builder.Configuration.AddJsonStream(FileSystem.OpenAppPackageFileAsync($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")}.json").Result);
//...
builder.Services.AddHttpClient<IGameClient, GameClient>(client =>
{
    client.BaseAddress = new(builder.Configuration.GetRequired("ApiBase"));
});