This website is a combination of blog
and business for Pendle Smith.
Welcome.

What I Learned While Attempting Dependency Injection with Windows Applications


While trying my hand at dependency injection in .NET I learned a lot about the structure of a WPF application, a little bit about MVVM (Model, View, ViewModel) architecture, and the difference between scoped, transient and singleton.

MVVM refers to there being a view (user interface) and then a model (the code behind it) that both interact with an intermediate/hybrid layer called the ViewModel. WPF applications serve MVVM architecture by having XAML serve as the user interface and allowing C# to work behind the scenes, working together to create a functional and dynamic application.

Dependency injection involves passing an instance of an object/service to a class versus the class having to create and manage it’s own dependency. This was necessary to both serve as an added layer of abstraction as well as serving to enable more efficient usage of resources across the application’s life cycle.

The first step was to remove the startup URI in App.xaml and create the following code in App.xaml.cs.

public partial class App : Application
{
public static IHost? AppHost { get; private set; }

public App()
{
    AppHost = Host.CreateDefaultBuilder()
        .ConfigureServices((hostContext, services) =>
        {
            services.AddSingleton<MainWindow>();
            services.AddSingleton<IInterface, Interface>();
        })
        .Build();
}

protected override async void OnStartup(StartupEventArgs e)
{
    await AppHost.StartAsync();

    var startupForm = AppHost.Services.GetRequiredService<MainWindow>();
    startupForm.Show();

    base.OnStartup(e);
}

protected override async void OnExit(ExitEventArgs e)
{
    await AppHost.StopAsync();

    base.OnExit(e);
}



Here I installed Microsoft Hosting to host my app and render the services I need (dependency injection) before startup calls MainWindow.xaml to launch the application.

I wasn’t aware I could manipulate OnStartup and OnExit methods using override so that was cool to learn. You will also notice above that I used “AddSingleton” for both services, meaning that for the entire life cycle of the application there will only be one MainWindow and only one Interface.

As I stated above, creating and passing around one Interface class will help resource efficiency, allowing me to continue to reuse the same service instead of creating a new one every time the Interface is called.

private readonly IInterface _Init;


public MainWindow(IInterface Init)
{
InitializeComponent();
_Init = Init;

}


Above is me taking in the Interface class within the MainWindow so that I can use it as a service as soon as the application starts up in whatever way I need.

Transient services provide each class a brand new object and scoped services provide a single object/service for each new request, allowing it to remain within the scope it was called for.

This post is to serve as a recollection of a few things I’ve learned from this process.

,