WPF DependencyInjection via Microsoft.Extensions.DependencyInjection and Microsoft.Extensions.Hosting
Install-Package Microsoft.Extensions.DependencyInjection; Install-Package Microsoft.Extensions.Hosting; Install-Package communityToolkit.mvvm;
//Define interface and implemented classes
using System; using System.Collections.Generic; using System.Text; namespace WpfApp7.Services { public interface ISampleService { string GetMessage(); void PerformAction(); } public interface IDataService { Task<List<string>> GetDataAsync(); } } // using System; using System.Collections.Generic; using System.Text; namespace WpfApp7.Services { public class SampleService : ISampleService { private readonly IDataService _dataService; public SampleService(IDataService dataService) { _dataService = dataService; } int idx = 0; public string GetMessage() { return $"{DateTime.Now.ToString("yyyyMMddHHmmssffff")}, this is DependencyInjection"; } public void PerformAction() { Console.WriteLine($"{DateTime.Now.ToString("yyyyMMddHHmmssffff")} action performed!"); } } public class DataService : IDataService { int idx = 0; public async Task<List<string>> GetDataAsync() { await Task.Delay(100); List<string> list = new List<string>(); for (int i = 0; i < 10000000; i++) { list.Add($"{++idx}_{Guid.NewGuid():N}"); } return list; } } }
//Register services in app.cs
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System.Configuration; using System.Data; using System.Windows; using WpfApp7.Services; namespace WpfApp7 { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : Application { private IHost host; public App() { host = Host.CreateDefaultBuilder() .ConfigureServices((context, services) => { ConfigurationServices(services); }).Build(); } private void ConfigurationServices(IServiceCollection services) { //Register services services.AddSingleton<IDataService, DataService>(); services.AddSingleton<ISampleService, SampleService>(); //Register view models services.AddTransient<MainVM>(); //Register views services.AddSingleton<MainWindow>(); } protected override async void OnStartup(StartupEventArgs e) { await host.StartAsync(); //Set the MainWindow from DI container var mainWin = host.Services.GetRequiredService<MainWindow>(); mainWin.Show(); base.OnStartup(e); } protected override async void OnExit(ExitEventArgs e) { using (host) { await host.StopAsync(TimeSpan.FromSeconds(5)); } base.OnExit(e); } public T GetService<T>() where T : class { return host.Services.GetService<T>(); } } }
//App.xaml remove startup uri
<Application x:Class="WpfApp7.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp7" > <Application.Resources> </Application.Resources> </Application>
//MainWindow.xaml
<Window x:Class="WpfApp7.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 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" WindowState="Maximized" xmlns:local="clr-namespace:WpfApp7" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding Msg}" Grid.Row="0" Grid.Column="0" FontSize="30"/> <Button Content="Load Data" Grid.Row="0" Grid.Column="1" Command="{Binding LoadDataCommand}"/> <ListView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding ItemsCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="FontSize" Value="30"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="FontSize" Value="50"/> <Setter Property="Foreground" Value="Red"/> </Trigger> </Style.Triggers> </Style> </ListView.ItemContainerStyle> <ListView.View> <GridView> <GridViewColumn Header="Items" DisplayMemberBinding="{Binding}" Width="{Binding DataContext.ListViewWidth, RelativeSource={RelativeSource AncestorType=Window}}"/> </GridView> </ListView.View> </ListView> <TextBlock Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" FontSize="50" Text="{Binding StatusMsg,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> </Grid> </Window> //MainWindow.cs using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp7 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } public MainWindow(MainVM viewModel) { InitializeComponent(); DataContext = viewModel; this.SizeChanged += MainWindow_SizeChanged; } private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e) { if(DataContext is MainVM vm) { vm.ListViewWidth = this.ActualWidth; } } } } //MainVM using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows.Input; using WpfApp7.Services; namespace WpfApp7 { public partial class MainVM : ObservableObject { private readonly ISampleService sampleService; private readonly IDataService dataService; private string msg; public string Msg { get { return msg; } set { msg = value; OnPropertyChanged(); } } private ObservableCollection<string> itemsCollection; public ObservableCollection<string> ItemsCollection { get { return itemsCollection; } set { itemsCollection = value; OnPropertyChanged(); } } public MainVM(ISampleService sampleServiceValue, IDataService dataServiceValue) { sampleService = sampleServiceValue; dataService = dataServiceValue; Msg = sampleService.GetMessage(); ItemsCollection = new ObservableCollection<string>(); LoadDataCommand = new RelayCommand(async () => await LoadDataAsync()); } private async Task LoadDataAsync() { StatusMsg = $"Loading..."; var dataList= await dataService.GetDataAsync(); foreach(var item in dataList) { ItemsCollection.Add(item); } StatusMsg = $"Loaded :{ItemsCollection.Count} items"; } public event PropertyChangedEventHandler? PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propName = "") { var handler = PropertyChanged; if (handler != null) { handler?.Invoke(this, new PropertyChangedEventArgs(propName)); } } public ICommand LoadDataCommand { get; } [ObservableProperty] private string statusMsg; [ObservableProperty] private double listViewWidth; } }



浙公网安备 33010602011771号