简体   繁体   中英

Using DI to Inject the Dependencies into ViewModel with MS DI and Catel.MVVM

My project is built with Catel.MVVM , but I am very open to any solution for WPF MVVM with DI that is not Catel.MVVM specific to solve my problem. The project is .NET 5.

I am struggling to get a solution for DI injecting dependencies into ViewModels with Catel.MVVM . I'm using the .NET Core implementation of DI.

What I want:

  1. Have DI inject dependencies into ViewModels when showing Views. Right now without a parameter-less constructor the ViewModel throws an exception due to the DI not creating the ViewModel.
  2. Have Catel.MVVM auto associate the ViewModel for each View so that it does not need to be set in XAML.

I know this is possible with Catel.MVVM because I see it working in the WildGums project LogViewer , but I am having trouble wrapping my head around how it works. I have also browsed through each WPF project in Catel.Examples . I'm either overlooking something or just do not understand how WPF MVVM with DI works. This is my first time using DI with MVVM.

I thought I would be lucky and this would be handled automatically if I use the naming conventions described in the docs .

I have a project with Catel.MVVM & working DI with the exception of ViewModel injection, CatelMvvmDI . As the project sits, ViewModel association is handled in XAML.

Register the View and ViewModel:

var viewModelLocator = _host.Services.GetRequiredService<IViewModelLocator>();
viewModelLocator.Register<MainView, MainViewModel>();

Show MainView:

var main = _host.Services.GetRequiredService<MainView>();
main.Show();

The correct view model type is resolved:

var viewModelLocator = _host.Services.GetRequiredService<IViewModelLocator>();
var viewModelType = viewModelLocator.ResolveViewModel(typeof(MainView));

This might be where I'm going wrong when registering the View & ViewModel:

services.AddSingleton<MainView>();
services.AddTransient<MainViewModel>();

Catel uses its own ServiceLocator by default. You can override any aspect of Catel by either implementing your own IServiceLocator / IDependencyResolver.

A simpler way for just vm's is to use a custom IViewModelFactory implementation.

Basically:

  1. To resolve views => IViewLocator
  2. To resolve view models => IViewModelLocator
  3. To create view models => IViewModelFactory

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM