wpf mvvm what does it mean to inject a service
Some time ago we talked most leveraging .NET Cadre features (like Host Architect, Service Provider and Dependency Injection) in WPF applications. Now it'due south fourth dimension to integrate them with the MVVM pattern. In this article we'll utilize MVVM Calorie-free, but but for what concerns helpers methods and classes for View Models. In particular, instead of its SimpleIoc, we'll bear witness how to use the .Net Cadre ServiceProvider. So, let's start from the lawmaking that we realized in the latest commodity and change information technology to add together MVVM support.
First of all, let's add together the MvvmLightLibsStd10 NuGet package to the project. And so, we need to create a ViewModel for our MainWindow. Keeping in mind that in our original sample the MainWindow receives two parameters in the constructor via Dependency Injection, we desire to move them to the View Model. And so, we'll have something similar this:
public class MainViewModel : ViewModelBase { private readonly ISampleService sampleService; individual readonly AppSettings settings; public MainViewModel(ISampleService sampleService, IOptions<AppSettings> options) { this.sampleService = sampleService; settings = options.Value; } }
Then, we need to alter the App.xaml.cs file to register this View Model. We also need to expose a reference to the ServiceProvider (we'll employ it later):
public partial form App : Application { individual readonly IHost host; public static IServiceProvider ServiceProvider { get; private set; } public App() { // Original host configuration... ServiceProvider = host.Services; } private void ConfigureServices(IConfiguration configuration, IServiceCollection services) { services.Configure<AppSettings>(configuration .GetSection(nameof(AppSettings))); services.AddScoped<ISampleService, SampleService>(); // Register all ViewModels. services.AddSingleton<MainViewModel>(); // Register all the Windows of the applications. services.AddTransient<MainWindow>(); } protected override async void OnStartup(StartupEventArgs e) { await host.StartAsync(); var window = ServiceProvider.GetRequiredService<MainWindow>(); window.Testify(); base of operations.OnStartup(e); } protected override async void OnExit(ExitEventArgs e) { // Original code... } }
At line 5 we declare a static reference to the IServiceProvider, that we assign at the end of the App constructor using the IHost.Services property (line 11). In the ConfigureServices method, line 22, we annals the MainViewModel. In this way, we can get information technology from the ServiceProvider and, more important, we tin can pass to its constructor all the dependencies it needs, that will be automatically resolved during instantiation (in this instance, AppSettings and ISampleService from lines 17-xix).
Notation that, typically, View Models are registered as singleton (line 22), but of course we tin decide to use the AddTransient method if necessary for our scenario. Moreover, for the sake of simplicity all the registrations are kept together in the same file, but of course information technology is possible to organize the code as we want.
Now we need to create the ViewModelLocator, i.e. a course that provides (every bit the name implies) references to View Models that will be bound to Views:
public grade ViewModelLocator { public MainViewModel MainViewModel => App.ServiceProvider.GetRequiredService<MainViewModel>(); }
In this case, we have only one View Model, every bit at lines three-4 we become information technology using the ServiceProvider property that is exposed by the App class. As we said earlier, all registrations are contained in the ConfigureServices method of the App class, so the ViewModelLocator need only to provide getter properties for View Models.
The last thing to do is to reference the ViewModelLocator in XAML and link the View Model to the View. And so, in the App.xaml file nosotros need to write something like this:
<Application x:Class="WpfNetCoreMvvm.App" ...> <Application.Resources> <ResourceDictionary> <vm:ViewModelLocator xmlns:vm="clr-namespace:WpfNetCoreMvvm.ViewModels" 10:Key="Locator" /> <!-- Application styles definition --> </ResourceDictionary> </Application.Resources> </Application>
And, finally, set the DataContext property of MainWindow.xaml:
<Window x:Course="WpfNetCoreMvvm.Views.MainWindow" ... DataContext="{Binding Source={StaticResource Locator}, Path=MainViewModel}">
Now everything is set. We tin put a breakpoint in the MainViewModel constructor and verify that it will be correctly invoked when the application starts, with all the dependencies it needs:
To make a further exam, we can add a bit of code to the View Model:
public class MainViewModel : ViewModelBase { private string input; public string Input { get => input; set => Gear up(ref input, value); } private readonly ISampleService sampleService; private readonly AppSettings settings; public RelayCommand ExecuteCommand { become; } public MainViewModel(ISampleService sampleService, IOptions<AppSettings> options) { this.sampleService = sampleService; settings = options.Value; ExecuteCommand = new RelayCommand(async () => await ExecuteAsync()); } private Job ExecuteAsync() { Debug.WriteLine($"Current value: {input}"); return Task.CompletedTask; } }
Now we take an Input belongings (lines 3-8) and a RelayCommand (line 13, with the implementation at lines 24-28). So, as usual, we tin use binding in our Window:
<Window ...> <Grid> <StackPanel HorizontalAlignment="Heart" VerticalAlignment="Centre"> <TextBlock Text="Input:" /> <TextBox Width="300" Text="{Binding Input, Way=TwoWay}" /> <Button Command="{Binding ExecuteCommand}" Content="Execute" /> </StackPanel> </Grid> </Window>
Let'southward attempt running the application:
You tin can download the sample application using the link below:
In the next article we'll add an important feature that is currently missing: the power to navigate through Window from View Models passing parameters to them upon activation.
Source: https://marcominerva.wordpress.com/2020/01/07/using-the-mvvm-pattern-in-wpf-applications-running-on-net-core/
0 Response to "wpf mvvm what does it mean to inject a service"
Post a Comment