Помогите разобраться с Microsoft.Extensions.DependencyInjection

Я хочу попытаться начать использовать di контейнеры для внедрения зависимостей.

Подскажите пожалуйста полный цикл работы с этим паттерном, библиотекой.

Например, у меня должно быть View у нее ViewModel, а у ViewModel есть несколько зависимостей - сервисы.

По идее как я нашел регистрируем View и ViewModel.

void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<MainWindow>();
    services.AddTransient<MainViewModel>();
}

Потом получаем каждую сущность из провайдера в поля и как обычно суем друг в друга и показываем.

var mainWindow = serviceProvider.GetService<MainWindow>();
var mainViewModel= serviceProvider.GetService<MainViewModel>();
mainWindow.DataContext = mainViewModel;
mainWindow.ShowDialog();

А как обстоят дела с сервисами для ViewModel, так же получать их в поля, а потом внедрять в конструктор??? Просто это должно быть по идее автоматическим делом.

Правильный ли код сверху с полями или же это делается как то по другому?


Ответы (1 шт):

Автор решения: aepot

У вас всё наоборот. Окно не должно быть синглтоном, как любое View. Время жизни View компонент контролирует WPF, а не вы. А вот вьюмодель наоборот - синглтон. Вы же разницу понимаете?

void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<MainViewModel>();
    services.AddTransient<MainWindow>();
}

Далее в окне в конструкторе

public MainWindow(MainViewModel vm)
{
    InitializeComponent();
    DataContext = vm;
}

И теперь резолвим

var mainWindow = serviceProvider.GetService<MainWindow>();
mainWindow.Show();

Готово, IoC контейнер сам создаст MainViewModel и сам её подсунет в конструктор окна.

Главное окно не надо вызывать через ShowDialog.

Если у вас дублируется окно, зайдите в App.xaml и уберите там StartupUri="MainWindow.xaml".


С другими сервисами точно так же. Регистрируете тип в контейнере, затем в конструкторе запрашиваете, и так по древовидной структуре контейнер построит вам все экземпляры.

На самом деле это я самое простое показал, и контейнер намного умнее и целую кучу штук умеет удобных. Документация.

→ Ссылка