18

Native versus Web Clients

Today, the opportunities to deliver incredible user interfaces are huge. We have plenty of great technologies, many ways to do so, and the most important thing, great hardware. But the key points for a software architect are the advantages and disadvantages of each UI technology.

This chapter will discuss how you, as a software architect, are impacted due to the different kinds of UI, something that naturally will be asked by the product owners. In addition, it presents the current options we have and the future, in the form of .NET MAUI.

The main purpose of a book that is focused on software architecture is not to go deep into the details of development technology, but discuss each of them to understand the best scenario in terms of where to use them. That is why, even considering that .NET MAUI will be released as GA in the second quarter of 2022, we decided to discuss the possibilities we will have with this great change.

In this chapter, we will cover the following topics:

  • Technologies focused on native development
  • Technologies focused on web development
  • Cross-platform technologies
  • A first look at .NET MAUI

Due to the characteristics of this chapter, there will not be a dedicated topic discussing the book use case. Instead, the WWTravelClub case will be presented during the discussion. In addition, due to a delay in the delivery of .NET MAUI, we will not present a detailed demo for it; we will instead explain how to test the .NET 6 MAUI preview versions.

Technical requirements

This chapter requires that you have the following:

Technologies focused on native development

Native development can be considered the beginning of UI development. When the idea first arised of developing software with another person, there was no concept of sharing code between machines with different hardware.

This is the first good answer as to why we have good performance on native applications. We cannot forget that native apps run better just because they are near the hardware, most of the time connected to the OS directly or by using a framework, such as .NET. Be careful; we are not only talking about native mobile apps, but we are also discussing apps delivered in Windows, Linux, Mac, Android, or any other OS that can run apps.

Considering this scenario, the big question is – when do I have to use a native app? There are some cases where this would be a good idea:

  • There is no need to deploy on different platforms.
  • There is a huge connection to the hardware.
  • The performance provided by a web client is not acceptable.
  • The application needs device resources that can’t be accessed through a browser because of a browser’s security policies.
  • The place where the application will run has connectivity problems.
  • The worst case is the one where you need two things at the same time: better performance than a web client and different platforms. In this scenario, you will have to probably deliver two applications, and the way you have designed the backend of this solution will be extremely important for reducing maintenance and costs as regards development.

The decision between developing native or not can be difficult to take without a proof of concept (POC). As a software architect, you should be the one to recommend this kind of POC.

But even when we talk about native development, we have more than one option. Let us talk about the options that you can use with .NET 6.

Windows Forms

Windows Forms was the first technology presented by Microsoft to deliver apps using C#. From this first release all the way up to .NET 6, Forms’s compatibility with new resources and APIs from the framework has evolved, but the delivery of UI components is basically the same as we had in 2002, when C# surged.

Tela de computador com texto preto sobre fundo branco  Descrição gerada automaticamente

Figure 18.1: Windows Forms development environment in Visual Studio 2022

It is worth mentioning that since .NET 5, we can work with Core Framework, and the advantage here is that we can make use of libraries that were created as cross-platform. When we choose this option, the SDK defined in the project is the same as web apps, but the target framework defined is net6.0-windows.

Microsoft provides a guide for migrating from Windows Forms with .NET Framework to Windows Forms with .NET 6 Framework. Check this out at https://docs.microsoft.com/en-us/dotnet/desktop/winforms/migration/.

Windows Forms is widely used all over the world and, therefore, migrating this legacy software to different solutions is not a cheap task. That is why Microsoft has decided to keep the Windows Forms project connected to the new framework versions.

Windows Presentation Foundation (WPF)

WPF projects were created as an alternative to developing applications focused on rich user interfaces, where 2D/3D rendering, vectoring graphics, animation, and other graphical resources were needed. The way we develop WPF apps is like HTML/CSS apps, but it requires the knowledge of XAML – Extensible Application Markup Language, a declarative markup language.

The same way we checked for Windows Forms, we are also able to develop and migrate our applications written in WPF to .NET 6. In fact, there is also a tool to help you with this, called .NET Portability Analyzer, which you can download at https://docs.microsoft.com/en-us/dotnet/standard/analyzers/portability-analyzer. Besides, you can find a tool that can assist you in moving your .NET Framework applications to .NET, called .NET Upgrade Assistant.

You can download it at https://dotnet.microsoft.com/en-us/platform/upgrade-assistant.

Tela de computador com texto preto sobre fundo branco  Descrição gerada automaticamente

Figure 18.2: WPF development environment in Visual Studio 2022

The advantage of using WPF, besides the possibility of having a fantastic variety of great user interfaces, is the usage of XAML, which was defined as a basis for developing many other user interface technologies, such as UWP, Xamarin.Forms, and .NET MAUI.

Xamarin

Xamarin is a technology incorporated by Microsoft in 2016 as part of Visual Studio. It comes from a project called Mono and, today, is an open source framework for building iOS and Android native apps with C#.

Tela de computador com texto preto sobre fundo branco  Descrição gerada automaticamente

Figure 18.3: Possibilities of building apps with Xamarin in Visual Studio 2022

The approach offered by Xamarin is that you can keep developing by using the C# language, sharing some code between Android and iOS, and, at the same time, having the performance required in native apps. In fact, while developing native apps, this is exactly what we have.

It is worth mentioning that the velocity at which the Xamarin team delivers the wrappers from new libraries provided by Apple and Google is incredible. Today, we basically cannot detect it, so we can say that any code that you can write in native apps for Android and iOS in their natural language can be written using C# with Xamarin.

Technologies focused on web development

There are many reasons why web development has increased in recent decades. The basic answer is the ability to deploy to many users, at the same time, in the new version of the application. Although today, we have stores that handle this situation for Google, Apple, and even Microsoft, at the beginning of this history, we did not have it.

Sometimes, the security policies that are automatically enforced by all browsers may encourage the usage and diffusion of web applications.

Another great reason why people started using web development instead of the native one is the space needed in the device to install the app. This was one of the reasons behind the emergence of Progressive Web Apps (PWAs).

In the last three chapters, we presented technologies focused on web development. In Chapter 15, Presenting ASP.NET Core MVC, we discussed the MVC model implemented using Razor to render HTML5/CSS3/JavaScript pages, which certainly can deliver great web apps today. In Chapter 16, Implementing Frontend Microservices with ASP.NET Core, we presented a complete and detailed example of how to use the frontend microservices approach in your web solution. In Chapter 17, Blazor WebAssembly, you had the opportunity to be in contact with this high-performance alternative to JavaScript.

So, a good question here would be, why is web development not used today? The best answer would be a lack of connectivity, and, as a software architect, you need to be alert to this, as we discussed in Chapter 2, Non-Functional Requirements.

Sometimes, it is not only a matter of having connectivity or not. Sometimes, the big problem is the instability, and don’t forget about the difficulties you will encounter from unexpected scenarios that web apps will generate once they’re out in the world.

For instance, in the WWTravelClub case, there is a first user story that says: “As a common user, I want to view promotional packages on the home page, so that I can easily find my next vacation.” At first sight, you may determine that a web app is the only alternative, especially because there is also a system requirement that says: “The system will run on the Windows, Linux, iOS, and Android platforms.” But for anyone, the experience of finding an error due to a lack of connectivity just as you find your next vacation is horrible! So maybe, for some parts of the solution, a local app with some data already downloaded would be nice.

For sure, a user’s experience is not the main responsibility of a software architect, but, on the other hand, we should always be the ones who enable solutions to evolve this experience.

Progressive web applications

Progressive web applications are single-page applications that run in the browser but that can be installed like native applications. Moreover, they can also run offline.

Progressive applications are a new web standard that is supported by all mainstream browsers. If you require all the advantages of web applications, but you also need the capability of working offline like a native application, progressive web applications are the right choice for you.

However, keep in mind that progressive web applications can’t ensure the same performance and flexibility as native applications.

Blazor projects, described in Chapter 17, Blazor WebAssembly, give you the option to publish the application as a progressive web application: it is sufficient to check the Progressive Web Application checkbox that appears when you create a Blazor project. This is all you need to do to create a Blazor progressive web application.

If you ship your Blazor application as a progressive application, you overcome the problem of the initial download time (4-8 seconds), which is the main disadvantage of Blazor, while keeping the advantage of an automatic application update. In fact, when a Blazor progressive application starts, if a connection is available and a more recent version has been published, the application updates automatically.

The option to install the Blazor progressive web application is not available during development because this would interfere with the usual modification-test cycle. Therefore, you need to publish your application to test its progressive application peculiarities.

It is worth pointing out that progressive applications must be organized to take full advantage of their capability to work offline. Therefore, following repeated communication errors, the application should save all the data to be sent to the server in the browser’s local storage, where it can be saved while waiting for a connection to be established successfully.

It is also possible to maintain the whole application state in a centralized service so that the user can serialize and save it to local storage before quitting the application. This way, when the application is offline, data to be sent to the server is not lost because it remains in the application state that is saved to disk.

When a progressive web application doesn’t fulfill your requirements either, you must support several different devices you should consider cross-platform technologies, which are discussed in the next section.

Cross-platform technologies

Although performance can be a difficult requirement to achieve, in many scenarios, due to the simplicity of the solution, this is not the Achilles’ heel of the application. Considering the WWTravelClub, although it would be useful to have this offline experience mentioned before, the performance itself is not the most difficult one to achieve.

In these scenarios, cross-platform technologies make total sense. Let us check Xamarin.Forms, the option we currently have for apps, and .NET MAUI, the approach designed by Microsoft for the near future.

Xamarin.Forms

Xamarin.Forms is the technology associated with Xamarin that enables cross-platform development. With it, you can deliver a single shared code for a user interface that adapts its view according to the device it is deployed on.

To do so, instead of using the same GUI environments from native apps, Xamarin.Forms uses XAML as the engine to design the interface. The Model-View-ViewModel design pattern is implemented in this scenario so that you can have this interface decoupled from the other layers.

The way Xamarin.Forms interacts with the OSes of each supported platform is interesting too. Basically, for each app supported (Android, iOS, Windows, and so on), we have a dedicated project that can even have specific implementations if needed:

Texto  Descrição gerada automaticamente

Figure 18.4: Xamarin.Forms set of projects

Since Xamarin.Forms is a good option for accelerating mobile development, it delivers some templates that help you out so you’re not starting from scratch:

Interface gráfica do usuário, Aplicativo, Teams  Descrição gerada automaticamente

Figure 18.5: Xamarin.Forms templates in Visual Studio 2022

It also provides a bunch of libraries to connect with the hardware, called Xamarin.Essentials. With Xamarin.Essentials, hardware access to geolocation and battery, for instance, is quite easy.

Some specific libraries accelerate mobile development, including the following:

  • Message Center: Publish-Subscribe implementation for communication between shared and native code
  • Dependency Service: A service locator that enables Xamarin.Forms applications to invoke native code from shared code
  • SQLite.NET: A wrapper to a SQLite database in C# to store data locally

Considering all the advantages presented today, the use of Xamarin.Forms would be the first choice for mobile development in the .NET world.

.NET MAUI

As we could see in the preceding topic, Xamarin.Forms is a great option while developing a cross-platform app, with good access to native sources. What if we could do the same thing we do in mobile apps in Android and iOS for Windows and macOS? This is the case with .NET MAUI (.NET Multi-platform App UI), which is a cross-platform framework for creating native mobile and desktop apps with C#.

The basis of .NET MAUI is Xamarin.Forms. In fact, Microsoft has provided a guide to migrate the original Xamarin.Forms apps to .NET MAUI, as can be verified at the following link: https://docs.microsoft.com/en-us/dotnet/maui/get-started/migrate. However, considering the architecture presented by Microsoft, .NET MAUI is probably the next generation for any native/desktop app development in C#:

Interface gráfica do usuário, Site  Descrição gerada automaticamente

Figure 18.6: .NET MAUI high-level architecture

There is a specific difference between Xamarin.Forms and .NET MAUI. In Xamarin.Forms, there is a specific native project for any kind of device we would like to publish to on the app, while in .NET MAUI, this will be placed as a multi-target platform.

Microsoft announced in September 2021 that .NET MAUI will not be available together with the delivery of .NET 6. Probably in the second quarter of 2022, we will have it to use as a GA SDK. Till then, as a software architect, you must try the new environment to check availability in your scenarios.

The next section explains how to use .NET MAUI in practice, and how to run a Blazor application as a native application with the help of .NET MAUI.

A first look at .NET MAUI

.NET MAUI is not installed by default when you install Visual Studio 2022. Furthermore, at this time, you will need the Visual Studio 2022 Preview version to do so. You can find it at https://visualstudio.microsoft.com/vs/preview/. If you have the MAUI workload installed, in the project creation wizard, you should be able to select C#/All platforms/MAUI, and then select .NET MAUI App, as shown here:

Figure 18.7: Creating a .NET MAUI application

If no MAUI selection appears in the right-hand menu, you need to install the MAUI workload. You can do it by clicking the Install more tools and features link at the bottom of the project selection menu:

Visual Studio workloads for .NET MAUI.

Figure 18.8: Installing the MAUI workload using Visual Studio 2022 Preview

Once you are in the installation wizard, ensure that the mobile workload is selected and then check the .NET MAUI checkbox in the workload detail that is on the right of the installation window.

Once you complete the project creation, you will see that the project contains App.xaml and MainPage.xaml files. Like Xamarin and WPF projects, MAUI projects also use xaml files to define components and resources.

The App.xaml file contains some application-level resources. More specifically, the initial App.xaml file defines the default appearance of the Button and Label components:

<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:windows="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.WindowsSpecific;assembly=Microsoft.Maui.Controls"
             xmlns:local="clr-namespace:MauiApp1"
             x:Class="MauiApp1.App"
             windows:Application.ImageDirectory="Assets">
    <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="PrimaryColor">#512bdf</Color>
            <Color x:Key="SecondaryColor">White</Color>
            <Style TargetType="Label">
                <Setter Property="TextColor" Value="{DynamicResource PrimaryColor}" />
                <Setter Property="FontFamily" Value="OpenSansRegular" />
            </Style>
            <Style TargetType="Button">
                <Setter Property="TextColor" Value="{DynamicResource SecondaryColor}" />
                <Setter Property="FontFamily" Value="OpenSansRegular" />
                <Setter Property="BackgroundColor" Value="{DynamicResource PrimaryColor}" />
                <Setter Property="Padding" Value="14,10" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

MainPage.xaml, instead, defines the application home page. It has an associated MainPage.xaml.cs code-behind file that contains page initialization code and the code of all event handlers attached to the events of the components used in the xaml file. In our case, MainPage.xaml.cs contains the definition of an OnCounterClicked event handler:

private void OnCounterClicked(object sender, EventArgs e)
{
    count++;
    CounterLabel.Text = $"Current count: {count}";
    SemanticScreenReader.Announce(CounterLabel.Text);
}

The preceding code increments a count private property defined in the code-behind class and attaches the result to the text of the CounterLabel label component that is defined in the xaml file:

<Label 
 Text="Current count: 0"
 Grid.Row="2"
 FontSize="18"
 FontAttributes="Bold"
 x:Name="CounterLabel"
 HorizontalOptions="Center" />

The SemanticScreenReader.Announce method sets the text to be used by the screen reader when the counter is incremented.

The OnCounterClicked handler is attached to the Clicked event of a button that is defined in the xaml file:

<Button 
 Text="Click me"
 FontAttributes="Bold"
 Grid.Row="3"
 SemanticProperties.Hint="Counts the number of times you click"
 Clicked="OnCounterClicked"
 HorizontalOptions="Center" />

The MauiProgram.cs file defines the Host application. As usual, there you can add configuration settings and all dependency injection services. Both the services and configurations defined there apply to all target platforms.

Platform-specific code can be added to the code files under the Platforms folder, which contains a subfolder for each target platform, specifically, Android, iOS, Mac Catalyst, and Windows, which each redefine the application endpoint with different techniques. Android defines a MainApplication.cs class that inherits from the MauiProgram.cs platform-independent entry point:

    [Application]
    public class MainApplication : MauiApplication
    {
        public MainApplication(IntPtr handle, 
            JniHandleOwnership ownership)
            : base(handle, ownership)
        {
        }
        protected override MauiApp CreateMauiApp() 
            => MauiProgram.CreateMauiApp();
    }

The constructor receives platform-specific information you can use in your code, while CreateMauiApp overrides the platform-independent host creation. As a default, this override just calls the original method.

However, you can customize the host creation for the Android platform by splitting the host creation in MauiApplication into several methods; one that adds services, another that adds configuration, and so on. This way, for instance, MainApplication can reuse the services defined in MauiApplication while adding new services.

iOS and Mac Catalyst call the platform-independent host creation in the AppDelegate.cs class that inherits from the abstract MauiUIApplicationDelegate MAUI class:

[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
    protected override MauiApp CreateMauiApp() => 
        MauiProgram.CreateMauiApp();
}

Again, by default, the platform-independent code is called, but you can customize the host creation with the same technique explained for Android.

You can define the platforms you want to support by editing the MAUI project file (right-click on the project file and select Edit Project File):

<PropertyGroup>
<TargetFrameworks>
    net6.0-windows;net6.0-ios;net6.0-android;net6.0-maccatalyst
</TargetFrameworks>
<OutputType>Exe</OutputType>
...

Since, if you try to compile for all platforms, you will be asked to install the Android SDK, and other iOS software, you can make a quick test by specifying just Windows:

<TargetFrameworks>net6.0-windows</TargetFrameworks>

Instead of describing in detail all the available xaml components, in the next subsection, we describe how to run an existing Blazor application as a native application with the help of MAUI.

.NET MAUI Blazor applications

.NET MAUI offers the possibility to run Blazor applications as native applications on all MAUI-supported platforms. In this case, Blazor code is not translated into WebAssembly, but runs with the same performance as a native application. This result is obtained with the implementation of a browser-like environment that runs .NET code directly instead of WebAssembly, and that doesn’t suffer from the security limitations of all browsers. Thus, for instance, the application can access the whole device filesystem without any limitations.

Blazor WebAssembly is perfectly compatible with MAUI Blazor, so you can basically run the same code you run in the browser as a native application. For this reason, MAUI Blazor applications are the ideal choice when you need native performance on all platforms supported by MAUI, but you want to run your application in the browser, too, either because you want to cover other platforms, or because you don’t want to force the user to install your application.

MAUI Blazor applications are also a good choice when you want to reuse the Blazor skills of your team to build native applications.

It is worth pointing out that, while standard MAUI applications offer a user experience that is specific for each supported platform, MAUI Blazor applications offer exactly the same user experience in all platforms. In some situations, this is an advantage, but in other situations, this is a disadvantage since the user will perceive that your application doesn’t look like a native application, but looks more like a web application.

Building a MAUI Blazor application is super easy and doesn’t require an in-depth knowledge of MAUI. It is enough to choose .NET MAUI Blazor App instead of .NET MAUI App in the project creation wizard:

Figure 18.9: MAUI Blazor app

Like all standard MAUI applications, a MAUI Blazor application also has a MauiProgram.cs entry point that can be customized for each specific supported platform thanks to the code contained in the Platforms folder. However, in this case, you should not perform any relevant customization since all platforms will run the same Blazor code.

The MAUI Blazor application contains the usual Shared and Pages folders where you can place your Blazor components and pages, and also a wwwroot folder containing the usual index.html page and all the CSS and JavaScript you might need. It also contains the usual _Imports.razor page where you can place all your default using statements.

A MAUI Blazor application also uses layout pages that you can place in the Shared folder and may reference Razor libraries containing CSS components and JavaScript files.

A Blazor root component is placed in the Main.cs file and has exactly the same structure as the root component of a Blazor web application.

The Blazor application is started by a MAUI component called BlazorWebView that is placed in the MAUI start page, MainPage.xaml:

<b:BlazorWebView HostPage="wwwroot/index.html">
    <b:BlazorWebView.RootComponents>
        <b:RootComponent Selector="app" ComponentType="{x:Type local:Main}" />
    </b:BlazorWebView.RootComponents>
</b:BlazorWebView>

The BlazorWebView component defines the Blazor component to use as the application root (the one defined in Main.razor) and the tag of the HTML element of where to render the application: Selector = "app".

The only difference in the code of a Blazor web application is the JavaScript bootstrap file contained in the index.html file, that is, _framework/blazor.webview.js.

All the services that you need to inject into the application can be placed in the MAUI Host definition in MauiProgram.cs:

var builder = MauiApp.CreateBuilder();
builder
    .RegisterBlazorMauiWebView()
    .UseMauiApp<App>()
    .ConfigureFonts(fonts =>
    {
        fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
    });
builder.Services.AddBlazorWebView();
//Put here your Blazor services
builder.Services.AddSingleton<WeatherForecastService>();
return builder.Build();

Pay attention when using an HttpClient class to communicate with a server. Blazor web applications may use URLs relative to the domain where they were downloaded, while MAUI Blazor applications must use absolute URLs since they are not associated with any default URL.

The reader is encouraged to turn the example application described in Chapter 17, Blazor WebAssembly, into a MAUI Blazor application. The simplest way to do this is to define a fresh new MAUI Blazor application and to copy files there from the Blazor web application.

Summary

In this chapter, we have analyzed some alternatives related to GUIs. The main purpose of the overview was to give to you, as a software architect, arguments to decide between one technology or another. Furthermore, we presented .NET MAUI, a near-future alternative for building cross-platform design interfaces for Windows, Android, iOS, and macOS.

The chapter also showed how to run a Blazor application as a native application with the help of .NET MAUI.

In the next chapter, Chapter 19, Artificial Intelligence and Machine Learning, we will explain how to add artificial intelligence to your applications.

Questions

  1. Is it possible to run Windows Forms applications using .NET 6?
  2. Is it possible to run WPF applications using .NET 6?
  3. When is native development recommended?
  4. When is web development recommended?
  5. What are the technologies that enable cross-platform publishing?

Further reading

Here are some useful links that can enhance your understanding of this topic:

Download the example code files

The code bundle for the book is hosted on GitHub at https://github.com/PacktPublishing/Software-Architecture-with-C-10-and-.NET-6-3E.

Join our book’s Discord space

Join the book’s Discord workspace for a Ask me Anything session with the authors:

https://packt.link/SAcsharp10dotnet6

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.60.29