le mie informazioni di contatto
Posta[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Questo articolo usa il progetto WPF Gallery per apprendere i concetti correlati all'inserimento delle dipendenze e come eseguire l'inserimento delle dipendenze in WPF.
Dependency Injection (DI) è un modello di progettazione utilizzato per implementare il principio di inversione del controllo (IoC). Lo scopo principale dell'iniezione delle dipendenze è trasferire la creazione di oggetti e la gestione delle dipendenze tra oggetti dall'interno dell'oggetto a un contenitore o framework esterno, migliorando così la manutenibilità, la testabilità e la flessibilità del codice.
Il concetto centrale dell'iniezione di dipendenza
Tipi di inserimento delle dipendenze
iniezione del costruttore: L'oggetto dipendente viene passato attraverso il costruttore della classe.
public class OrderService
{
private readonly IProductRepository _productRepository;
public OrderService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
}
Iniezione di proprietà: gli oggetti dipendenti vengono passati attraverso le proprietà pubbliche della classe.
public class OrderService
{
public IProductRepository ProductRepository { get; set; }
}
metodo di iniezione: L'oggetto dipendente viene passato attraverso il parametro del metodo della classe.
public class OrderService
{
public void ProcessOrder(IProductRepository productRepository)
{
// 使用 productRepository 处理订单
}
}
Dependency Injection (DI) è un modello di progettazione attraverso il quale la creazione di oggetti e la gestione delle dipendenze tra oggetti possono essere trasferite dall'interno dell'oggetto a un contenitore o framework esterno. Esistono diversi motivi e vantaggi importanti per l'inserimento delle dipendenze:
Questo articolo utilizza il progetto Galleria WPF per apprendere come utilizzare l'inserimento delle dipendenze nell'indirizzo del codice WPF:
https://github.com/microsoft/WPF-Samples/blob/main/SampleApplications/WPFGallery
Per implementare l'inserimento delle dipendenze in questo progetto, vengono utilizzati questi due pacchetti:
Per prima cosa guarda il contenuto di 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();
}
}
Cos'è IHost?
In C#,IHost
è un'interfaccia utilizzata in .NET per creare e configurare applicazioniHost
concetto astratto.IHost
Un'interfaccia definisce una raccolta di servizi e componenti necessari per avviare, eseguire e gestire un'applicazione. Viene in genere utilizzato con le applicazioni ASP.NET Core, ma funziona anche con altri tipi di applicazioni .NET, ad esempio applicazioni console o programmi WPF.
IHost
L'interfaccia è composta daHostBuilder
Implementazione della classe, che prevede la creazione e la configurazione diIHost
metodi di istanza.HostBuilder
Consente di aggiungere vari servizi come registrazione, configurazione, contenitori di inserimento delle dipendenze, ecc. e di configurare il comportamento di avvio e arresto dell'applicazione.
Fornisce metodi pratici per la creazione di istanze Microsoft.Extensions.Hosting.IHostBuilder con impostazioni predefinite preconfigurate.
Restituisce un IHostBuilder.
Aggiungi servizi al contenitore. Questa operazione può essere richiamata più volte e i suoi risultati sono cumulativi.
Il significato del parametro configureDelegate è configurare il delegato di Microsoft.Extensions.DependencyInjection.IServiceCollection.
Questa raccolta verrà utilizzata per costruire System.IServiceProvider.
Il delegato richiede due tipi di parametri: HostBuilderContext e IServiceCollection, che non hanno valore restituito.
Qui viene passata un'espressione Lambda che soddisfa il tipo delegato.
In C#,() => {}
È una sintassi per le espressioni Lambda. Le espressioni Lambda sono un wrapper delegato leggero che consente di definire un metodo anonimo e passarlo come parametro a un metodo che supporta delegati o alberi delle espressioni.
Le espressioni lambda forniscono un modo conciso per definire i metodi e sono utili soprattutto quando è necessario passare metodi come parametri ad altri metodi.
Quando si aggiungono servizi, qui ci sono due cicli di vita, oltre a AddSingleton e AddTransient, c'è anche AddScoped.
Questi metodi definiscono il ciclo di vita del servizio, ovvero il modo in cui le istanze del servizio vengono create e gestite nell'applicazione.
AggiungiSingleton
AggiungiTransiente
Aggiungi ambito
utilizzare questi servizi
Nella funzione principale:
avviare_host
,passaggio_host.Services.GetRequiredService<MainWindow>();
Ottieni l'istanza MainWindow.
Prendendo come esempio la classe MainWindow, visualizza il costruttore di MainWindow in 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;
}
Dopo aver rimosso il contenuto non pertinente a questo argomento, risulta quanto segue:
public MainWindow(MainWindowViewModel viewModel, IServiceProvider serviceProvider, INavigationService navigationService)
{
_serviceProvider = serviceProvider;
ViewModel = viewModel;
_navigationService = navigationService;
}
Hai notato che non hai più bisogno di creare nuovi oggetti da solo? La creazione di questi oggetti è gestita dal contenitore di iniezione delle dipendenze. Quando questi oggetti sono necessari, possono essere iniettati tramite il costruttore come adesso.
Se l'inserimento delle dipendenze non viene utilizzato, potrebbe assomigliare a questo:
public MainWindow()
{
_serviceProvider = new IServiceProvider();
ViewModel = new MainWindowViewModel();
_navigationService = new INavigationService();
}
Questo articolo introduce innanzitutto il concetto di inserimento delle dipendenze, quindi spiega perché è necessario l'inserimento delle dipendenze e infine illustra come utilizzare l'inserimento delle dipendenze in WPF tramite il progetto WPF Gallery.
1、[WPF-Samples/Sample Applications/WPFGallery su main · microsoft/WPF-Samples (github.com)](https://github.com/microsoft/WPF-Samples/tree/main/Sample Applications/WPFGallery)