Dependency Injection for Windows and Uno Platform Applications.

In the next few posts we’re going to be looking at the TubePlayer sample application for the Uno Platform. For this post we’re going to focus on using Uno.Extensions to add dependency injection to an Uno Platform application. Uno.Extensions builds on the awesome work that Microsoft has done with the Microsoft.Extensions that provides capabilities such as DI, Configuration, Logging, Http and much more that can be used within an application. Everything covered in this post applies equally to building an application that uses the Windows App Sdk (WinUI), without using the Uno Platform to target other platforms.

Getting Started

Since this is the first in this series, we’ll take a moment to create the application that we’ll use for the subsequent posts. We’ll use the dotnet new template, unoapp, which can be install by executing dotnet new install uno.templates. Once the templates have been installed, we’ll create the template using the following options.

dotnet new unoapp -preset blank -tfm net8.0 -markup csharp -presentation mvux -theme material -di -config -http -nav regions -log default -toolkit -server -auth msal -o TubePlayerWithAuth 
  • Preset: Blank
  • Framework: .NET 8.0
  • Presentation: MVUX
  • Markup: C# Markup
  • Theme: Material
  • Extensions: DI, Configuration, Http, Navigation(Regions), Logging(Default)
  • Features: Toolkit, Server
  • Authentication: MSAL

We’ll cover the details of these options as we get into the subsequent blog posts but for now this will create a runnable applicaiton that has the pages and models that we need.

IHost and HostBuilder

Rather than attempting to explain the logic that the template creates by default, we’re going to recreate the initialization logic for the application from scratch. The logic for initializing the application is in the app.cs in the OnLaunched method.

protected async override void OnLaunched(LaunchActivatedEventArgs args)
{
    .... Initialize application here
}

We’ll start by using the CreateBuilder extension method to create an IApplicationBuilder instance, which is a wrapper around IHostBuilder from Microsoft.Extensions.Hosting. In addition to exposing the Build method, similar to the IHostBuilder, the IApplicationBuilder exposes properties to access the Application instance, the main Window of the application and the launch arguments.

protected async override void OnLaunched(LaunchActivatedEventArgs args)
{
    var builder = this.CreateBuilder(args)
        .Configure(host => host
                .... Initialize IHostBuilder
        );
    Host = builder.Build();
    MainWindow = builder.Window;
    MainWindow.Activate();
}

Note: If you’re adding support IHostBuilder/IHost support to an existing Uno Platform application, add a reference to Uno.Extensions.Hosting.WinUI to the main project of the application.

After the Build method is invoked on the IApplicationBuilder the MainWindow can be activated, which will display the application. However, nothing will be displayed inside the application window. For now we’ll add a Frame and manually navigate to MainPage.

protected async override void OnLaunched(LaunchActivatedEventArgs args)
{
    var builder = this.CreateBuilder(args)
        .Configure(host => host
                .... Initialize IHostBuilder
        );

    Host = builder.Build();

    MainWindow = builder.Window;
    var frame = new Frame();
    MainWindow.Content = frame;
    frame.Navigate(typeof(MainPage));
    MainWindow.Activate();
}

Now that we have the initialization logic for the application, we can access the IHost instance that’s returned from the Build method. Specifically, we can access the Services property that returns an IServiceProvider instance that can be used to access registered services from the DI container.

In the following code, we’ve adapted the initialization logic to change the environment to Development when running in Debug. The environment can be retrieved later by accessing the IHostEnvironment instance from the DI container.

protected async override void OnLaunched(LaunchActivatedEventArgs args)
{
    var builder = this.CreateBuilder(args)
        .Configure(host => host
#if DEBUG
            // Switch to Development environment when running in DEBUG
            .UseEnvironment(Environments.Development)
#endif
            );

    Host = builder.Build();
    var env = Host.Services.GetService<IHostEnvironment>();

    MainWindow = builder.Window;
    var frame = new Frame();
    MainWindow.Content = frame;
    frame.Navigate(typeof(MainPage));
    MainWindow.Activate();
}

In this post we’ve seen a brief introduction to getting started with Uno.Extensions in order to setup and access a DI container within an application. We’ll see in future posts how features such as Configuration and Logging can be configured on the IHostBuilder for use throughout the application.

5 thoughts on “Dependency Injection for Windows and Uno Platform Applications.”

Leave a comment