Reputation: 1449
Background:
I implemented dependency injection in a WPF application using Microsoft.Extensions.DependencyInjection.
App.xaml.cs
protected override async void OnStartup(StartupEventArgs e)
{
AppHost = Host.CreateDefaultBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddTransient<IFileRepository, FileRepository>();
services.AddSingleton<MainWindow>();
}).Build();
await AppHost!.StartAsync();
var startupForm = AppHost.Services.GetRequiredService<MainWindow>();
startupForm.Show();
base.OnStartup(e);
}
In my OpenProjectViewModel, I inject the fileRepository.
public IFileRepository fileRepository { get; }
public OpenProjectViewModel(IFileRepository _fileRepository)
{
fileRepository = _fileRepository;
}
In OpenProjectView.xaml I set the datacontext
<UserControl.DataContext>
<local:OpenProjectViewModel/>
</UserControl.DataContext>
The problem
When that app starts, it doesn't like that I don't have a parameterless constructor in OpenProjectViewModel. When I add a parameterless constructor in OpenProjectViewModel, the app starts but the fileRepository is then empty because it hasn't been injected.
The question
Is there a way to let the app know when it should inject the FileRepository when the OpenProjectViewModel is being used? I followed this guide to set up the DI. But Tim shows you how to set it up in the view code-behind.
Let me know if I missed sharing anything. Thank you for all the help in advance.
Upvotes: 1
Views: 1613
Reputation: 12276
You can't instantiate a viewmodel in XAML unless you're relying on the parameterless constructor.
You should use
AppHost.Services.GetRequiredService <MainWindowViewModel>()
And set DataContext
of MainWindow
in code to the result.
That will then pass IFileRepository
in as a parameter to the constructor.
Upvotes: 3