At work, we are planning to migrate our WPF application from .NET Framework 4.7 to .NET Core 3.0. The main reason for doing so is that it was always a big pain to organize the updates of the .NET Framework on our customer machines. So being able to bundle .NET Core with our application is a big plus for us. Then, for sure, we are looking for the performance improvements brought by .NET Core and finally the new capabilities brought by the fast pace of innovation of .NET Core.
This is a great opportunity for us to see and renew a part of the libraries we depend on.
In the current version of our application, we are using StructureMap as our IOC container. As you might have read StructureMap has been sunsetted and replaced by Lamar.
We could have gone to Lamar as it maintains API compatibility with SturtureMap. I just did not want to bring the dependency to Roslyn, but it seems that it was changed in Lamar 3.0. So, we surely will consider it.
As a first try, I would like to have a look at the IOC container brought by the ASP.NET team; Microsoft Extensions DependencyInjection. Even if it was brought by the ASP.NET team it doesn’t mean at all that it cannot be used outside of ASP.NET!
It is marked as Fast by Daniel Palme in his post ‘IoC Container Benchmark - Performance comparison‘, so it is a good candidate.
The goal of this post is to see how we could use Microsoft Extensions DependencyInjection in a .NET Core 3.0 with WPF. We will start really easily by creating a new WPF application with the .NET Core CLI.
Project creation
We create our project from the command line.
1 | ❯ mkdir WpfIoc |
What we want to achieve is to bootstrap the application and inject in the constructor of our MainWindow a service which will be called to display some text on the main window of the application.
Code
First, we need to add the reference to the Microsoft Extensions DependencyInjection.
1 | <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> |
Then we create an interface ITextService which will be injected by the container into the MainWindow class.
1 | public interface ITextService |
In fact, it is a concrete implementation of that interface which will be injected TextService.
1 | class TextService : ITextService |
Then we need to configure our IOC container.
1 | services.AddSingleton<ITextService>(provider => new TextService("Hi WPF .NET Core 3.0!")); |
So this also means that we need to have our IOC container creating our WPF MainWindow, no problem it is just another normal C# class.
1 | services.AddSingleton<MainWindow>(); |
Next piece which we need to put in place is the one linking all the other pieces together; the IOC container! That’s quite easy we just need to extend the App class to create ServiceCollection add the dependencies we want the IOC container to manage and then to call BuildServiceProvider.
1 | public App() |
Then, on the App_OnStartup we are using the ServiceProvider to get an instance of MainWindow which would get the ITextService injected in its constructor.
1 | private void App_OnStartup(object sender, StartupEventArgs e) |
We also modified App.xaml to call App_OnStartup.
1 | <Application x:Class="wpfioc.App" |
Finally, we modify the XAML of the MainWindow to display some text in a Label.
1 | <Window x:Class="WpfIoc.MainWindow" |
And we inject through the constructor, the ITextService interface which is used to set the Label text.
1 | public partial class MainWindow : Window |
Result
We can run the application and see that TextService is called and the WPF application correctly displays the text.
You can get all the code on GitHub