I want to use .NET Generic Host in my .NET 8.0 WPF application and utilize IHostApplicationLifetime for some custom setup and teardown actions. One guide I've found in internet has the following approach:
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using System;
public class Program
{
[STAThread]
public static void Main()
{
// creating application host
var host = Host.CreateDefaultBuilder()
// injecting services
.ConfigureServices(services =>
{
services.AddSingleton<App>();
services.AddSingleton<MainWindow>();
})
.Build();
// getting a service - App class object
var app = host.Services.GetService<App>();
// starting application
app?.Run();
}
}
Where App.cs code is:
using System.Windows;
public class App : Application
{
readonly MainWindow mainWindow;
// getting main windows object via DI
public App(MainWindow mainWindow)
{
this.mainWindow = mainWindow;
}
protected override void OnStartup(StartupEventArgs e)
{
mainWindow.Show(); // displaying main window
base.OnStartup(e);
}
}
But as I can see in this approach application host is used only as DI. And host.Start() or host.StartAsync() is not called I cannot utilize IHostApplicationLifetime even if I implement some hosted service:
public class MyHostedService : IHostedService
{
public MyHostedService(IHostApplicationLifetime appLifetime)
{
appLifetime.ApplicationStarted.Register(OnStarted);
appLifetime.ApplicationStopping.Register(OnStopping);
}
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
private void OnStarted()
{
//my custom setup actions here
}
private void OnStopping()
{
//my custom teardown actions here
}
}
and inject it into application host with services.AddHostedService<MyHostedService>(); If I add host.Start() before app?.Run() line - it begins to work.
But is it a correct approach? Or is there another way to utilize IHostApplicationLifetime in code sample above?
UPDATE: I also planned to reuse MyHostedService class in a couple of console applications (also with the help of .NET Generic Host and ServiceCollection). I hope this to be a convenient way to inject a the service with same setup and teardown actions in different application types. In fact, I just need to catch the moment of starting and closing for wpf and console applications.
IHostApplicationLifetime, as well as the whole ServiceCollection and Host, are not designed to be run in an UI application, as UI has its own "hosting" structure, different from UI-independent Host.
However, you can still use the benefits of the ServiceCollection, like DI, logging, configuration, etc, by just not using the Run() method on a built container. I can see you understand that part.
Now, for the IHostApplicationLifetime part. If you were using the Host's default approach, an implementation of IHostApplicationLifetime would be created by the framework for you.
However, in your case, the Host doesn't have a ready-to-use implementation of how your real host behaves, when it starts or stops, so you might want to create your own, WPF-based implementation.
That, or you could use some community-based already made solutions, such as Dapplo.Microsoft.Extensions.Hosting.Wpf (concrete example).
.ConfigureWpf<MainWindow>()
.UseWpfLifetime()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With