Maui Hybrid application and a Blazor
Since Java first came out, I have been trying to use the same code for both a desktop client and a web client. It was easy to do this for the backend. Getting a shared UI across a desktop and a web client that provided the same experience, was not possible. Add in the support for Android and iOS and you end up with 4 UI code bases, 4 UI teams, 4 QA teams, etc. Maui Blazor Hybrid to the rescued.
With Maui Blaozr I can finally achieve that goal. In my last post, "Let’s Make a Blazor Hybrid Application!" I showed how to create a simple Maui Blazor hybrid application. I now took the next step, added a Blazor Web Assembly application, and using the Shared library, I created a hosted web client and a desktop client, with the same UI. Here is how I did it.
Desktop Application
- Create a Share UI library project
- Move the Pages Folder into the new library
- Move the Shared Folder into the new library
- Move the CSS folder into the new library
- Create a new Shared Service Library
- Move the WeatherForecast data class into the new library
- Move the WeatherForecast Service class into the new library
- In the Maui Project
- Create a project reference to the new Shared UI library
- Create a project reference to the new Shared Service Library
- Add the shared UI values to the router initialization.
- This is the tricky part. In order for the Maui application to see the shared UI, it needs a reference to it in the router.
- To achieve this, add the following to the <Router AppAssembly> tag
<Router AppAssembly="@typeof(Main).Assembly" AdditionalAssemblies="new[] { typeof(BlazorHybridSharedUI.Pages.Index).Assembly, typeof(BlazorHybridSharedUI.Shared.MainLayout).Assembly }">
4. Build, run, and test
Both Web Client
- Add a new Web Client
- I added a Blazor Server and a Blazor web assembly. The steps are similar except for the WeatherForecast Service.
- Remove the Page folder
- Remove the Shared Folder
- Add a project reference to the Share UI Lib project
- Add a project reference to the Shared Service Lib project
- Add the shared UI values to the router initialization.
- This is the tricky part. In order for the Maui application to see the shared UI, it needs a reference to it in the router.
- To achieve this, add the following to the <Router AppAssembly> tag
- <Router AppAssembly="@typeof(Main).Assembly" AdditionalAssemblies="new[] { typeof(BlazorHybridSharedUI.Pages.Index).Assembly, typeof(BlazorHybridSharedUI.Shared.MainLayout).Assembly }">
Web Assembly Client
The web assembly client added a different twist than the Desktop. The WetherForecast Page gets its data from locally in the Desktop Application while the Balzor web assembly application gets its data from an API.
To solve this, I simply added a flag, "Hosted", that I set to true when the web assembly client called the weather service. Based on that flag, it would either use the local method to return the weather forecast data or use the API.
{
if (hosted)
{
return await APIManager();
}
else
{
return await GetLocalData(startDate);
}
}
private async Task<WeatherForecast[]> GetLocalData(DateTime startDate)
{
return await Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(startDate.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
}).ToArray());
}
private async Task<WeatherForecast[]> APIManager()
{
HttpClient httpClient = new();
var result = await httpClient.GetFromJsonAsync<WeatherForecast[]>("https://localhost:7198/WeatherForecast");
if (result == null)
{
result = Array.Empty<WeatherForecast>();
}
return result;
}
Comments
Post a Comment