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;
    }
}

 

 

 

 

 

 

 

image

 

 

 

 

 

 

 

 

image

 

posted @ 2025-09-15 16:52  FredGrit  阅读(9)  评论(0)    收藏  举报