IvoL
IvoL

Reputation: 113

Xamarin Forms Dependency Injection with Microsoft.Extensions.DependencyInjection

I am trying to set up basic DI with the standard Microsoft.Extensions.DependencyInjection NuGet package.

Currently I am registering my dependencies like this:

public App()
{
    InitializeComponent();
    var serviceCollection = new ServiceCollection();
    ConfigureServices(serviceCollection);
}

private static void ConfigureServices(ServiceCollection serviceCollection)
{
    serviceCollection.AddSingleton<IRestClient>(_ => new RestClient("https://localhost:44379/api/"));
    serviceCollection.AddScoped<ICommHubClient, CommHubClient>();
}

I use a viewModel that requires dependencies like this:

 public ChatListViewModel(
        ICommHubClient client,
        IRestClient restClient
        )

In the code behind file of a page (.xaml.cs) I need to supply the viewModel but I need to provide the dependencies there as well.

public ChatListPage()
{
     InitializeComponent();
     BindingContext = _viewModel = new ChatListViewModel(); //CURRENTLY THROWS ERROR BECAUSE NO DEPENDENCIES ARE PASSED!
}

is there anyone who knows how I can apply Dependency Injection (registering and resolving) with Microsoft.Extensions.DependencyInjection in Xamarin Forms?

Upvotes: 2

Views: 1519

Answers (1)

Mateus Henrique
Mateus Henrique

Reputation: 198

You should also register your ViewModels in DI Container, not only your services:

In App.xaml.cs change your code to:

public ServiceProvider ServiceProvider { get; }

public App()
{
    InitializeComponent();
    
    var serviceCollection = new ServiceCollection();
    ConfigureServices(serviceCollection);
    ServiceProvider = serviceCollection.BuildServiceProvider();
    
    MainPage = new ChatListPage();
}

private void ConfigureServices(ServiceCollection serviceCollection)
{
    serviceCollection.AddSingleton<IRestClient>(_ => new RestClient("https://localhost:44379/api/"));
    serviceCollection.AddScoped<ICommHubClient, CommHubClient>();
    serviceCollection.AddTransient<ChatListViewModel>();
}

And then you can resolve your ViewModel from ServiceProvider

public ChatListPage()
{
    InitializeComponent();
    BindingContext = _viewModel = ((App)Application.Current).ServiceProvider.GetService(typeof(ChatListViewModel)) as ChatListViewModel;
}

Upvotes: 3

Related Questions