моя контактная информация
Почтамезофия@protonmail.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
В этой статье используется проект галереи WPF, чтобы изучить соответствующие концепции внедрения зависимостей и способы выполнения внедрения зависимостей в WPF.
Внедрение зависимостей (DI) — это шаблон проектирования, используемый для реализации принципа инверсии управления (IoC). Основная цель внедрения зависимостей — перенести создание объектов и управление зависимостями между объектами изнутри объекта во внешний контейнер или фреймворк, тем самым улучшая сопровождаемость, тестируемость и гибкость кода.
Основная концепция внедрения зависимостей
Типы внедрения зависимостей
внедрение конструктора: Зависимый объект передается через конструктор класса.
public class OrderService
{
private readonly IProductRepository _productRepository;
public OrderService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
}
Внедрение свойств: Зависимые объекты передаются через общедоступные свойства класса.
public class OrderService
{
public IProductRepository ProductRepository { get; set; }
}
метод инъекции: Зависимый объект передается через параметр метода класса.
public class OrderService
{
public void ProcessOrder(IProductRepository productRepository)
{
// 使用 productRepository 处理订单
}
}
Внедрение зависимостей (DI) — это шаблон проектирования, с помощью которого создание объектов и управление зависимостями между объектами можно перенести изнутри объекта во внешний контейнер или платформу. Существует несколько важных причин и преимуществ внедрения зависимостей:
В этой статье используется проект галереи WPF, чтобы узнать, как использовать внедрение зависимостей в адрес кода WPF:
https://github.com/microsoft/WPF-Samples/blob/main/SampleApplications/WPFGallery
Для реализации внедрения зависимостей в этом проекте используются эти два пакета:
Сначала просмотрите содержимое App.xaml.cs:
public partial class App : Application
{
private static readonly IHost _host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
services.AddSingleton<INavigationService, NavigationService>();
services.AddSingleton<MainWindow>();
services.AddSingleton<MainWindowViewModel>();
services.AddTransient<DashboardPage>();
services.AddTransient<DashboardPageViewModel>();
services.AddTransient<ButtonPage>();
services.AddTransient<ButtonPageViewModel>();
services.AddTransient<CheckBoxPage>();
services.AddTransient<CheckBoxPageViewModel>();
services.AddTransient<ComboBoxPage>();
services.AddTransient<ComboBoxPageViewModel>();
services.AddTransient<RadioButtonPage>();
services.AddTransient<RadioButtonPageViewModel>();
services.AddTransient<SliderPage>();
services.AddTransient<SliderPageViewModel>();
services.AddTransient<CalendarPage>();
services.AddTransient<CalendarPageViewModel>();
services.AddTransient<DatePickerPage>();
services.AddTransient<DatePickerPageViewModel>();
services.AddTransient<TabControlPage>();
services.AddTransient<TabControlPageViewModel>();
services.AddTransient<ProgressBarPage>();
services.AddTransient<ProgressBarPageViewModel>();
services.AddTransient<MenuPage>();
services.AddTransient<MenuPageViewModel>();
services.AddTransient<ToolTipPage>();
services.AddTransient<ToolTipPageViewModel>();
services.AddTransient<CanvasPage>();
services.AddTransient<CanvasPageViewModel>();
services.AddTransient<ExpanderPage>();
services.AddTransient<ExpanderPageViewModel>();
services.AddTransient<ImagePage>();
services.AddTransient<ImagePageViewModel>();
services.AddTransient<DataGridPage>();
services.AddTransient<DataGridPageViewModel>();
services.AddTransient<ListBoxPage>();
services.AddTransient<ListBoxPageViewModel>();
services.AddTransient<ListViewPage>();
services.AddTransient<ListViewPageViewModel>();
services.AddTransient<TreeViewPage>();
services.AddTransient<TreeViewPageViewModel>();
services.AddTransient<LabelPage>();
services.AddTransient<LabelPageViewModel>();
services.AddTransient<TextBoxPage>();
services.AddTransient<TextBoxPageViewModel>();
services.AddTransient<TextBlockPage>();
services.AddTransient<TextBlockPageViewModel>();
services.AddTransient<RichTextEditPage>();
services.AddTransient<RichTextEditPageViewModel>();
services.AddTransient<PasswordBoxPage>();
services.AddTransient<PasswordBoxPageViewModel>();
services.AddTransient<ColorsPage>();
services.AddTransient<ColorsPageViewModel>();
services.AddTransient<LayoutPage>();
services.AddTransient<LayoutPageViewModel>();
services.AddTransient<AllSamplesPage>();
services.AddTransient<AllSamplesPageViewModel>();
services.AddTransient<BasicInputPage>();
services.AddTransient<BasicInputPageViewModel>();
services.AddTransient<CollectionsPage>();
services.AddTransient<CollectionsPageViewModel>();
services.AddTransient<MediaPage>();
services.AddTransient<MediaPageViewModel>();
services.AddTransient<NavigationPage>();
services.AddTransient<NavigationPageViewModel>();
services.AddTransient<TextPage>();
services.AddTransient<TextPageViewModel>();
services.AddTransient<DateAndTimePage>();
services.AddTransient<DateAndTimePageViewModel>();
services.AddTransient<StatusAndInfoPage>();
services.AddTransient<StatusAndInfoPageViewModel>();
services.AddTransient<SamplesPage>();
services.AddTransient<SamplesPageViewModel>();
services.AddTransient<DesignGuidancePage>();
services.AddTransient<DesignGuidancePageViewModel>();
services.AddTransient<UserDashboardPage>();
services.AddTransient<UserDashboardPageViewModel>();
services.AddTransient<TypographyPage>();
services.AddTransient<TypographyPageViewModel>();
services.AddSingleton<IconsPage>();
services.AddSingleton<IconsPageViewModel>();
services.AddSingleton<SettingsPage>();
services.AddSingleton<SettingsPageViewModel>();
services.AddSingleton<AboutPage>();
services.AddSingleton<AboutPageViewModel>();
}).Build();
[STAThread]
public static void Main()
{
_host.Start();
App app = new();
app.InitializeComponent();
app.MainWindow = _host.Services.GetRequiredService<MainWindow>();
app.MainWindow.Visibility = Visibility.Visible;
app.Run();
}
}
Что такое IHost?
В С#,IHost
это интерфейс, который используется в .NET для создания и настройки приложений.Host
понятие абстрактное.IHost
Интерфейс определяет набор служб и компонентов, необходимых для запуска, запуска приложения и управления им. Обычно он используется с приложениями ASP.NET Core, но также работает с другими типами приложений .NET, такими как консольные приложения или программы WPF.
IHost
Интерфейс состоит изHostBuilder
Реализация класса, обеспечивающая создание и настройкуIHost
методы экземпляра.HostBuilder
Позволяет добавлять различные службы, такие как ведение журнала, настройка, контейнеры внедрения зависимостей и т. д., а также настраивать поведение при запуске и остановке вашего приложения.
Предоставляет удобные методы для создания экземпляров Microsoft.Extensions.Hosting.IHostBuilder с предварительно настроенными значениями по умолчанию.
Возвращает IHostBuilder.
Добавьте сервисы в контейнер. Эту операцию можно вызывать несколько раз, и ее результаты суммируются.
Смысл параметра configureDelegate заключается в настройке делегата Microsoft.Extensions.DependencyInjection.IServiceCollection.
Эта коллекция будет использоваться для создания System.IServiceProvider.
Делегату требуются два типа параметров: HostBuilderContext и IServiceCollection, которые не имеют возвращаемого значения.
Здесь передается лямбда-выражение, соответствующее типу делегата.
В С#,() => {}
Это синтаксис лямбда-выражений. Лямбда-выражения — это облегченная оболочка делегата, которая позволяет вам определить анонимный метод и передать его в качестве параметра методу, поддерживающему делегаты или деревья выражений.
Лямбда-выражения предоставляют краткий способ определения методов, и они особенно полезны, когда вам нужно передавать методы в качестве параметров другим методам.
При добавлении сервисов здесь есть два жизненных цикла, кроме AddSingleton и AddTransient, есть еще AddScoped.
Эти методы определяют жизненный цикл службы, то есть то, как экземпляры службы создаются и управляются в приложении.
ДобавитьСинглтон
ДобавитьПереходный
AddScoped
используйте эти услуги
В основной функции:
запускать_host
,проходить_host.Services.GetRequiredService<MainWindow>();
Получите экземпляр MainWindow.
Взяв в качестве примера класс MainWindow, просмотрите конструктор MainWindow в MainWindow.xaml.cs:
public MainWindow(MainWindowViewModel viewModel, IServiceProvider serviceProvider, INavigationService navigationService)
{
_serviceProvider = serviceProvider;
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
Toggle_TitleButtonVisibility();
_navigationService = navigationService;
_navigationService.Navigating += OnNavigating;
_navigationService.SetFrame(this.RootContentFrame);
_navigationService.Navigate(typeof(DashboardPage));
WindowChrome.SetWindowChrome(
this,
new WindowChrome
{
CaptionHeight = 50,
CornerRadius = default,
GlassFrameThickness = new Thickness(-1),
ResizeBorderThickness = ResizeMode == ResizeMode.NoResize ? default : new Thickness(4),
UseAeroCaptionButtons = true
}
);
this.StateChanged += MainWindow_StateChanged;
}
После удаления не относящегося к данной теме контента, получается следующее:
public MainWindow(MainWindowViewModel viewModel, IServiceProvider serviceProvider, INavigationService navigationService)
{
_serviceProvider = serviceProvider;
ViewModel = viewModel;
_navigationService = navigationService;
}
Вы заметили, что вам больше не нужно создавать новые эти объекты самостоятельно? Созданием этих объектов управляет контейнер внедрения зависимостей. Когда эти объекты необходимы, их можно внедрить через конструктор, как сейчас.
Если внедрение зависимостей не используется, это может выглядеть так:
public MainWindow()
{
_serviceProvider = new IServiceProvider();
ViewModel = new MainWindowViewModel();
_navigationService = new INavigationService();
}
В этой статье сначала представлена концепция внедрения зависимостей, затем объясняется, почему необходимо внедрение зависимостей, и, наконец, рассказывается, как использовать внедрение зависимостей в WPF с помощью проекта галереи WPF.
1、[WPF-Samples/Samples Applications/WPFGallery на главной · microsoft/WPF-Samples (github.com)](https://github.com/microsoft/WPF-Samples/tree/main/Samples/WPFGallery)