C
C#15mo 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
Henkypenky15mo 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
zynthh15mo ago
Thats not my code dude. thats where the exception is thrown
zynthh
zynthh15mo 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
zynthh15mo ago
I setup DI as shown in this video. They used the non-null assertion operator there. So, any more suggestions?
Henkypenky
Henkypenky15mo ago
where is this code from? not following
zynthh
zynthh15mo 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
Henkypenky15mo ago
you are building the app, downloading it from tim corey's video? didn't modify anything?
zynthh
zynthh15mo 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
Henkypenky15mo ago
sure, good luck, perhaps someone more proficient in WPF can help more
phaseshift
phaseshift15mo 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
zynthh15mo ago
Thanks for your feedback. I tried adding it both as a scoped and a transient service but the same error remains.
Pobiega
Pobiega15mo ago
SomePage isn't added to the service collection, so it wont be created by DI, thus SomeService wont be injected
zynthh
zynthh15mo 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
Pobiega15mo 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
zynthh15mo 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
Pobiega15mo 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
Mayor McCheese15mo ago
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
phaseshift15mo 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
Pobiega15mo ago
I mean, sure you can manually resolve the known dependencies of something and then call the ctor but its pretty rare
zynthh
zynthh15mo 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
Accord15mo 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
ricecracker223415mo ago
@zynth initialize AppHost in the OnStartup event it seems that OnStartup event is called before the constructor for whatever reason
Accord
Accord15mo 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
zynthh15mo ago
The constructor is being called before. I verified this by stepping through with the debugger.
Accord
Accord15mo 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
More Posts
❔ SQL Table to ObjectI have a SQL Table "Card" with a column "CardNr" and a column "CardType". How would I make this in t❔ How to pull nuget packages from private Github registry when doing dotnet restore in Github actionDoes anyone know how to run `dotnet restore` from a Github action on a project that uses nuget packa❔ how can i re use the readline after using it in a if statementso basically im using readline and if it == "hello" for example, it'd writeline "hi!", then the prog❔ Moq test exception thrown after adding and saved changes to the context object```Exception has occurred: CLR/Moq.MockException Exception thrown: 'Moq.MockException' in Moq.dll: '❔ Make package C private in project A, which inherits project B which uses package CI have 2 projects, project A and B. project A inherits project B (dependency). however, I want proj❔ Possible to have whole app margin/padding in NET MAUI?Would it be possible to have an internal margin/padding for the whole presentation of the app?❔ error 8007006EHello, when I want to publish my WPF application with ClickOnce, I have an error: 8007006E and I don✅ No IntelliSense in VSCodeHey, my VSCode is lacking of IntelliSense when I code in C#. I tried everything, I'm full of despair❔ Splittings UT8 textI have an UTF8 text file text that is delimited by `╚` for lines and then further by `&` for values.❔ Weird SocketAsyncEventArgs server behaviourwhat might be the reason for this? All i'm doing is accepting a connection with SocketAsyncEventArgs