How-To: Manually Resolving Dependencies with CommunityToolkit.Mvvm
While making gradual changes to an existing app's codebase, you may find it necessary to access the DI container to manually resolve dependencies. For instance, if you are overhauling a view model to separate its logic into services, you may need to resolve the service without using constructor injection. The CommunityToolkit.Mvvm package provides a static Ioc.Default property that exposes the DI container used by the application.
This tutorial will walk you through how to set up this feature and use it to manually resolve dependencies.
Warning
This approach to resolving dependencies is not recommended, and should serve primarily as a stopgap measure while you refactor your codebase to use constructor injection.
Step-by-steps
Important
This guide assumes you used the template wizard or dotnet new unoapp to create your solution. If not, it is recommended that you follow the instructions for creating an application from the template.
1. Add the CommunityToolkit.Mvvm package to your project
- Add the CommunityToolkit.Mvvm package to your project.
2. Register services with the DI container
Register services with the DI container as you normally would. For instance, you can use the
Configuremethod onIHostBuilderto register services with the DI container:private IHost host { get; set; } protected override void OnLaunched(LaunchActivatedEventArgs args) { var appBuilder = this.CreateBuilder(args) .Configure(hostBuilder => { hostBuilder.ConfigureServices(services => services .AddSingleton<IPrimaryService, PrimaryService>() .AddSingleton<ISecondaryService, SecondaryService>() ); }); host = appBuilder.Build(); }
3. Configure the DI container to use the CommunityToolkit.Mvvm service provider
Observe that the built
IHostinstance is available to theApp.csfile. It is stored in a property on theAppclass:private IHost host { get; set; }Because the
IHostinstance is available to theApp.csfile, you can get theIHost.Servicescollection and configure the service provider to use it.To do so, add the following line to the
OnLaunchedmethod:protected override void OnLaunched(LaunchActivatedEventArgs args) { ... Ioc.Default.ConfigureServices(host.Services); }
4. Resolve services from the DI container
You can now resolve services from the DI container using the
Ioc.Defaultproperty. For instance, you can resolve theIPrimaryServiceservice in a view model that is not registered with the DI container.Do this by calling
GetServiceorGetRequiredServicemethod on the singleton provider instance:public class MainViewModel : ObservableRecipient { private readonly IPrimaryService? primaryService; private readonly ISecondaryService secondaryService; public MainViewModel() { // Get the IPrimaryService instance if available; otherwise returns null. primaryService = Ioc.Default.GetService<IPrimaryService>(); // Get the ISecondaryService instance if available; otherwise throws an exception. secondaryService = Ioc.Default.GetRequiredService<ISecondaryService>(); } }