C
C#2y ago
zynthh

❔ ✅ Trouble getting Dependency Injection to work in a WPF application

Hi, I think I'm losing my mind. I cannot get DI to work in my WPF application. What I'm trying to do is, inject a DbContext into a custom service class which is injected into a Page. Page:
public partial class SomePage : Page
{
private readonly ISomeService _someService;

public SomePage(ISomeService someService)
{
InitializeComponent();
_someService = someService;
}
}
public partial class SomePage : Page
{
private readonly ISomeService _someService;

public SomePage(ISomeService someService)
{
InitializeComponent();
_someService = someService;
}
}
Service:
public class SomeService : ISomeService
{
private readonly DataContext _context;

public SomeService(DataContext context)
{
_context = context;
}
}
public class SomeService : ISomeService
{
private readonly DataContext _context;

public SomeService(DataContext context)
{
_context = context;
}
}
Application DI setup:
using app.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Windows;
using app.Services;

namespace app;

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

public App()
{
AppHost = Host.CreateDefaultBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton<MainWindow>();
services.AddDbContext<DataContext>();
services.AddSingleton<ISomeService, SomeService>();
})
.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);
}
}
using app.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Windows;
using app.Services;

namespace app;

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

public App()
{
AppHost = Host.CreateDefaultBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton<MainWindow>();
services.AddDbContext<DataContext>();
services.AddSingleton<ISomeService, SomeService>();
})
.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);
}
}
When I try to build the app I get the attached error. I don't know how to debug this, it's probably something very obvious to some of you. Any help would be greatly appreciated!
25 Replies
Henkypenky
Henkypenky2y ago
paramOder is a jagged array you never initialize the elements also paramoder[i], ??? remember, it's a jagged array also if you have NRE enabled stop using the null forgiving operator (!) you either disable it or check for nulls properly
zynthh
zynthhOP2y ago
Thats not my code dude. thats where the exception is thrown
zynthh
zynthhOP2y ago
IAmTimCorey
YouTube
Dependency Injection in WPF in .NET 6 Including the Factory Pattern
.NET Core has a built-in dependency injection that we use in every web project type we create. However, did you know that you can also use that same dependency injection in the .NET Core version of WPF? In this video, we are going to enable dependency injection in WPF and then use it for some common scenarios, including creating multiple forms. ...
zynthh
zynthhOP2y ago
I setup DI as shown in this video. They used the non-null assertion operator there. So, any more suggestions?
Henkypenky
Henkypenky2y ago
where is this code from? not following
zynthh
zynthhOP2y ago
When I build the app, this exception that you can see in the screenshot is thrown. You can see in the top bar it says DefaultBinder.cs. It's some sort of internal .NET file.
Henkypenky
Henkypenky2y ago
you are building the app, downloading it from tim corey's video? didn't modify anything?
zynthh
zynthhOP2y ago
No, I transferred it into my project. He didn't have an example for what I'm trying to achieve. That is, injecting a dependency into another dependency basically. I just found out that, if I remove the injection of SomeService in SomePage, the app builds just fine. It's getting late here, I appreciate your help. I will be active here again tomorrow. Hopefully I can get this to work. Or rather, we can get this to work 😄
Henkypenky
Henkypenky2y ago
sure, good luck, perhaps someone more proficient in WPF can help more
phaseshift
phaseshift2y ago
You're basically making a captive db-context. DataContext is a scoped service. You're adding SomeService as singleton - this means that (I)SomeService will be using DataContext after DataContext has been disposed. I'm not sure if this is directly related to your current issue, but it definitely must be fixed at some point. Singleton services must not take scoped dependencies as ctor args.
zynthh
zynthhOP2y ago
Thanks for your feedback. I tried adding it both as a scoped and a transient service but the same error remains.
Pobiega
Pobiega2y ago
SomePage isn't added to the service collection, so it wont be created by DI, thus SomeService wont be injected
zynthh
zynthhOP2y ago
That doesn't work either. I don't want to inject SomePage anywhere, so why would I need to register it? I mean I tried it but it still doesnt't work. I want to inject SomeService into SomePage. And SomeService is registered. Maybe it's the way SomePage is being used in my MainWindow?
<Frame x:Name="SomeFrame" Source="Pages/SomePage.xaml" Loaded="SomePage_Loaded" />
<Frame x:Name="SomeFrame" Source="Pages/SomePage.xaml" Loaded="SomePage_Loaded" />
Could that be a reason for my error?
Pobiega
Pobiega2y ago
for SomeService to be injectable into SomePage, SomePage must be registered. thats how DI works. you then request a SomePage from the service provider somehow
zynthh
zynthhOP2y ago
OK that doesn't sound very good tbh. I'm wondering now, if you're even supposed to use DI with WPF that way. Have you used it in that way before? Or maybe someone else? I would love your feedback. 😄 In the end I could always just instantiate my Service normally in SomePage and everything should work, right?
Pobiega
Pobiega2y ago
I have used DI with WPF, but I've never done anything complicated in WPF I've created viewmodels and windows via it, I dont even know what a "Page" is in WPF terminology
Mayor McCheese
I don't frequently see the page model in wpf in the wild tbh I've never invested time in it. From what I recall of journal system in wpf you'd be in service locator land, but my expertise here is limited
phaseshift
phaseshift2y ago
It's not, at least not always in ms land. The web controllers are a big example where they are not themselves in the container by default Also not in unity container, I believe
Pobiega
Pobiega2y ago
I mean, sure you can manually resolve the known dependencies of something and then call the ctor but its pretty rare
zynthh
zynthhOP2y ago
Thanks all for your answers. I think my question was kind of answered, but I guess I will just normally instantiate an instance of my Service in my Page and use DI where nothing "frontend" is involved. Or if anyone knows a way how I can achieve it (maybe by refactoring the Page to a Component idk) please let me know. (I don't really know the WPF terminology, this is my first contact with the framework, I'm sorry.)
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
ricecracker2234
@zynth initialize AppHost in the OnStartup event it seems that OnStartup event is called before the constructor for whatever reason
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
zynthh
zynthhOP2y ago
The constructor is being called before. I verified this by stepping through with the debugger.
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server