Search code examples
c#mvvmdependency-injectionuno-platform

How can I use Microsoft.Extensions.DependencyInjection in an UNO Platform app


I am new to UNO Platform and I am trying to develop my first application with this framework. I would like to use a DI toolkit also so I chose Microsoft.Extensions.DependencyInjection that should be compliant with this Platform.

By the way, I cannot understand how can I inject dependencies to my ViewModels. I red this post: How can I use Microsoft.Extensions.DependencyInjection in an .NET Core console app? and this is my approach:

App.xaml.cs:

    public App()
    {
        ConfigureFilters(global::Uno.Extensions.LogExtensionPoint.AmbientLoggerFactory);

        var services = new ServiceCollection()
            .AddSingleton<IMessageBroker, MessageBroker>();
        var serviceProvider = services.BuildServiceProvider();

        this.InitializeComponent();
        this.Suspending += OnSuspending;
    }

where IMessageBroker and MessageBroker are the interface and the implementation of my class I would like to handle with DI. Then on my ViewModel I do:

MainPageViewModel.cs

public MainPageViewModel(IMessageBroker broker)
{
     // some code
}

So far, so good.

For MVVM toolkit, I chose MVVM helpers. If I understood correctly, this MVVM toolkit does not provide any convention to attach View to ViewModel so I should do it manually:

MainPage.xaml.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();

        // How can I get a reference to ServiceProvider for calling GetService
        var broker = serviceProvider.GetService<IMessageBroker>()

        this.DataContext = new MainPageViewModel(broker);
    }
}

How can I get a reference here to ServiceProvider for calling GetService<IMessageBroker>()?

Any hint would be highly appreciated.


Solution

  • one way you could do is having a static class ServiceLocator, which is initialized only from the beginning. This class exposes a readonly ServiceProvider, and you can call it to get the thing you register.

    You may read somewhere else, or someone else here may comment this is anti-pattern, which is generally out of context. Depending on what you are trying to do and how your solution is structured, this service locator pattern can be totally fine.

    here is a sample project you can use for reference https://github.com/weitzhandler/UnoRx/tree/f2a0771e6a513863108e58ac7087078f39f7e3ed

    an alternative will be, writing a viewmodel locator, which automatically resolves all dependencies through your view. This, however, may or may not overkill your use case.

    finally, my personal flavor, having a shell project that depends on auto discovery and auto resolving; and each discovered smaller projects will internally depends on either service locator or function compositions