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-step
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 Creating an application with Uno.Extensions documentation to create an application from the template.
1. Add CommunityToolkit.Mvvm to your project
Add
Mvvm
to the<UnoFeatures>
property in the Class Library (.csproj) file. This will add the CommunityToolkit.Mvvm package to your project.<UnoFeatures> Material; Extensions; + Mvvm; Toolkit; </UnoFeatures>
2. Register services with the DI container
Register services with the DI container as you normally would. For instance, you can use the
Configure
method onIHostBuilder
to 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
IHost
instance is available to theApp.cs
file. It is stored in a property on theApp
class:private IHost Host { get; set; }
Because the
IHost
instance is available to theApp.cs
file, you can get theIHost.Services
collection and configure the service provider to use it.To do so, add the following line to the
OnLaunched
method: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.Default
property. For instance, you can resolve theIPrimaryService
service in a view model that is not registered with the DI container.Do this by calling
GetService
orGetRequiredService
method 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>(); } }