Dependency Injection in .NET Core 3.0 for WPF

user842818 picture user842818 · Feb 26, 2019 · Viewed 10.8k times · Source

I’m quite familiar with ASP.NET Core and the support for dependency injection out of the box. Controllers can require dependencies by adding a parameter in their constructor. How can dependencies be achieved in WPF UserControls? I tried adding a parameter to the constructor, but that didn’t work. I love the IOC concept and would prefer to bring this forward to WPF.

Answer

maytham-ɯɐɥʇʎɐɯ picture maytham-ɯɐɥʇʎɐɯ · Oct 20, 2019

I have recently come across this requirement to my project and I solved it this way.

For Dependency Injection in .NET Core 3.0 for WPF. After you create a WPF Core 3 project in your solution, you need to install/add NuGet packages:

Microsoft.Extensions.DependencyInjection

In my case, I created a class called LogBase that I want to use for logging, so in your App class, add the following (and ya this is just a basic example):

private readonly ServiceProvider _serviceProvider;

public App()
{
    var serviceCollection = new ServiceCollection();
    ConfigureServices(serviceCollection);
    _serviceProvider = serviceCollection.BuildServiceProvider();
}
    
private void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ILogBase>(new LogBase(new FileInfo($@"C:\temp\log.txt")));
    services.AddSingleton<MainWindow>();
}
    
private void OnStartup(object sender, StartupEventArgs e)
{
    var mainWindow = _serviceProvider.GetService<MainWindow>();
    mainWindow.Show();
}

In your App.xaml, add Startup="OnStartup" so it looks like this:

<Application x:Class="VaultDataStore.Wpf.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:VaultDataStore.Wpf"
             Startup="OnStartup">
    <Application.Resources>
        
    </Application.Resources>
</Application>

So in your MainWindow.xaml.cs, you inject ILogBase in the constructor like this:

private readonly ILogBase _log;

public MainWindow(ILogBase log)
{
    _log = log;

    ...etc.. you can use _log over all in this class

In my LogBase class, I use any logger I like in my way.

I have added all this together in this GitHub repo.


Meanwhile, I have been asked how to use injection inside user control. I come up with this solution if some one get the benefit of it. Check it here.