MVVM dependency injection in child ViewModels
Deze opzet maakt het mogelijk dat ViewModels repositories of andere afhankelijkheden ontvangen via constructor-injectie.
Patroon Overzicht
De ViewModel van het child control wordt geleverd als een property in
de MainWindowViewModel. In XAML wordt de DataContext van het child
control gebonden aan deze property met
DataContext="{Binding ChildControlViewModel}". Dit maakt
het mogelijk om de child ViewModel via de constructor te injecteren,
terwijl de view zelf parameterloos blijft.
Opmerking: hoewel dit voorbeeld Avalonia gebruikt, is hetzelfde patroon toepasbaar op WPF, .NET MAUI, Uno en andere .NET MVVM-frameworks. Het kernidee—afhankelijkheden injecteren in child ViewModels via de parent en de DataContext van de child control binden—is framework-onafhankelijk.
Implementatie Stappen
Registreer de services en ViewModels.
App.axaml.cspublic class App : Application { public static IServiceProvider Services { get; private set; } = default!; public override void Initialize() { AvaloniaXamlLoader.Load(this); } public override void OnFrameworkInitializationCompleted() { ServiceCollection services = new(); services.AddTransient<IRepository, Repository>(); services.AddTransient<ChildControlViewModel>(); services.AddTransient<MainWindowViewModel>(); Services = services.BuildServiceProvider(); if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { desktop.MainWindow = new MainWindow { DataContext = Services.GetRequiredService<MainWindowViewModel>(), Topmost = true }; } base.OnFrameworkInitializationCompleted(); } }Maak het child viewmodel en implementeer constructor injection
ChildControlViewModel.cspublic class ChildControlViewModel(IRepository repository) { public ObservableCollection<string> Items { get; } = new ObservableCollection<string>(repository.GetItems()); }Injecteer het ChildControlViewModel in de MainViewModel
MainWindowViewModel.cspublic class MainWindowViewModel(ChildControlViewModel childControlViewModel) : ViewModelBase { public ChildControlViewModel ChildControlViewModel { get; } = childControlViewModel; }Verbind het child ViewModel in Xaml.
MainWindow.xaml<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vlc="clr-namespace:LibVLCSharp.Avalonia;assembly=LibVLCSharp.Avalonia" xmlns:exampleApp="using:ExampleApp" xmlns:vm="using:ExampleApp.ViewModels" x:Class="ExampleApp.Views.MainWindow" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" Icon="/Assets/avalonia-logo.ico" Title="Example App"> <Design.DataContext> <vm:MainWindowViewModel /> </Design.DataContext> <exampleApp:ChildControl DataContext="{Binding ChildControlViewModel}" Grid.Row="1" /> </Window>