In the previous article, we’ve seen how to install/update the prerequisites that are necessary to work with .NET MAUI Preview 8 application.
In this article, we’re going to see the changes that got newly introduced as part of this preview and what’s changed from the earlier ones.
The most important thing is now WinUI artifacts, targeting the Windows platform, are now part of the Single project, the original design goal of .NET MAUI. Yes, one single project for all 4 presently supported target platforms. WinUI works on top of WindowsAppSDK, rebranded from Project Reunion, 1.0 (experimental) version.

If you’re working on a new project in Preview 8, you need to uncomment this TargetFrameworks
tag containing the Windows target definition in the Project file. Use Ctrl + K + U
shortcut key to avoid any error.

The target SDK version for Android is pushed to API level 31 (Android 12.0 – codenamed S) and hence it requires OpenJDK 11.

Below is the screenshot of the project artifacts, the orange arrow indicates wherever it is impacted in Preview 8.

To work with this single project, use the dropdown to the left of the Play button and open the Framework sub-menu to switch to a different target platform, and then choose the appropriate device (physical/virtual) to run the application.

The execution of the application code will always start from the target platform and then, at some point, the control transfers to this cross-platform (shared) code. From there on, it is a neat abstraction down the line.
To know more about this, we need to look at how each of the platform works:
Let’s start with Android, execution starts from the MainApplication
class that is marked with the [Application]
attribute (in MainApplication.cs). This class inherits from the class titled MauiApplication
, an abstract class with an abstract method named CreateMauiApp()
returning an instance of type MauiApp
. The definition for this abstract method is to be provided in this MainApplication class.

Next let’s look at iOS and Mac Catalyst, since both of them are from the Apple family, they follow a similar construct:
Execution starts from the Main()
method (in Program.cs). In which, UIApplication.Main()
method is invoked with a reference to AppDelegate type. Here, AppDelegate
class inherits from the class titled MauiUIApplicationDelegate
, again an abstract class with an abstract method named CreateMauiApp()
returning an instance of type MauiApp
. The definition for this abstract method is to be provided in this AppDelegate class.


Finally, let’s look at the Windows platform, execution starts from the Main()
method (in Program class), there invoking the Application.Start()
method with the instance of the App class (see the definition of InitializeComponent() method in App.xaml.cs). This App
class inherits from the class titled MauiWinUIApplication
, again an abstract class with an abstract method named CreateMauiApp()
returning an instance of type MauiApp
. The definition for this abstract method is to be provided in this App class.

This certainly brings some fond memories of the initial days of my learning career with Microsoft Foundation Class (MFC), a precursor to Windows Forms. In which, to build an app, a class needs to be inherited from CWinApp
, an abstract class with an abstract method titled InitInstance()
that returns an instance of the type CWinApp in its definition. Near identical pattern.
Needless to say, all these platforms follow a similar pattern. Whenever there is a similarity, it can be moved to the shared code. Hence at this juncture, the execution transfers to the shared code.
This is where the proven Host Builder pattern starts to appear and is fully integrated into the App startup. As type MauiApp
(a sealed class) is nothing but an implementation of IHost
interface and is more versatile than the previous IStartup
kind of implementation as it now includes Services, Configuration, Logging, and Lifetime.

In the shared code, a static method named CreateMauiApp()
is defined (in MauiProgram.cs) that returns an instance of type MauiApp
.
At first, CreateBuilder()
method is called to initialize the Host (returns an object of type MauiAppBuilder
).
Next, the shared App
class is hooked into the Host Builder using the UseMauiApp<App>()
generic method call (remember App class defines the MainPage and that’s the first UI to get rendered).
Then this is where all customizations are to be registered like Handlers, Compatibility Renderers, Effects, Essentials, Fonts, Lifecycle Events, Services, etc … To do so, invoke the appropriate Configure*
extension methods. To define services, use the Services
property on the builder object. Can be further simplified by writing extension methods, if necessary.
And then, the Build()
method is to be invoked on the builder object and the return type is MauiApp
.
Finally, this method, MauiProgram.CreateMauiApp(), is invoked in all the platforms for the must-define abstract method.
And there is a commonality in all the platform-specific base types by defining the below properties:
- Current
- A read-only static property of the containing type (like Application.Current in shared code)
- Services
- A read-write (write – restricted to only its derivatives) property of type
IServiceProvider
– DI Container
- A read-write (write – restricted to only its derivatives) property of type
- Application
- A read-write (write – restricted to only its derivatives) property of type
IApplication
– Nothing but the shared application class instance.
- A read-write (write – restricted to only its derivatives) property of type
This can be made use of to access the Services from the DI container as mentioned below. The return type is same for all the platforms.
#if ANDROID
MauiApplication.Current.Services;
#elif IOS || MACCATALYST
MauiUIApplicationDelegate.Current.Services;
#elif WINDOWS10_0_17763_0_OR_GREATER
MauiWinUIApplication.Current.Services;
#else
null;
#endif
To migrate working code from the earlier previews, copy the Windows folder as it is from the WinUI project and paste it into the Platforms folder. Replace the IStartup implementation with the new Abstract based pattern.
To run Windows target, do the necessary changes in the project file as highlighted in the screenshot and the launchSettings.json file is required to be present in the Properties folder. Can be copied from the older project and do the below-mentioned change.

If you come across the issue where the build is successful but deployment not done, then check whether the option is enabled from the Build menu -> Configuration Manager option. Both Build and Deploy checkbox needs to be in a checked state.

In this post, we’ve seen how .NET MAUI application works in Preview 8 and in the next post, we’ll see the customizations in the CreateMauiApp() method.
Happy coding. Stay connected as we continue to learn and share the experiences from this exciting journey of being a software developer.
5 replies on “.NET MAUI – What’s New in Preview 8”
[…] do a follow-up article (now available to read) on the new features in Preview 8 and the differences with the project […]
LikeLike
[…] .NET MAUI – What’s New in Preview 8 (Vijay Anand E G) […]
LikeLike
[…] Fiediaiev) Improving performance App using compiled bindings in Xamarin Forms (Leomaris Reyes) .NET MAUI – What’s New in Preview 8 (Vijay Anand E G) Users can customize iOS App Icons after downloading their Xamarin app (The First […]
LikeLike
[…] Take a look at this article to know more on the application startup that is pertaining to the latest preview (Preview 8 as of […]
LikeLike
[…] .NET MAUI – What’s New in Preview 8 (Vijay Anand E G) […]
LikeLike