mardi 6 octobre 2020

What is the best way to implement loose coupling in my Xamarin.Forms MVVM app

I started working on a new Xamarin.Forms app and ran into an interesting problem.

The following components are relevant:

VIEW: MainPage.xaml/.cs

VIEWMODEL: MainPageViewModel.cs

MODEL: AnApi.cs (Important: 'AnApi' implements interface 'IAnApi')

Here's the problem: I want there to be loose coupling between my ViewModel (MainPageViewModel) and the API (AnApi) to enable unit testing, which is why it would make sense to pass a parameter of type IAnApi to the constructor of MainPageViewModel, but the only way that is possible would be to instantiate MainPageViewModel either in the code behind of 'MainPage' or in 'App.cs'. As far as I understand that would break the MVVM pattern as the view would access a model, which it's not meant to. <-- This is where I might be wrong?

The other way to get this to work would be to just instantiate 'AnApi' in 'MainPageViewModel', but then you don't have loose coupling

Code below, even though it would of course be different depending on which solution you implemented.

AnApi.cs

    public interface IAnApi
    {
        Task<string> GetInformationAsync();
    }

AnApi.cs

    public class AnApi : IAnApi
    {
        public async Task<string> GetInformationAsync()
        {
            //...Code
        }
    }

MainPageViewModel.cs VARIANT 1 = Loose coupling, but broken MVVM?

    class MainPageViewModel
    {
        private IAnApi api;

        public MainPageViewModel(IAnApi apiConnector)
        {
            this.api = apiConnector;
        }

        public async Task RetrieveData()
        {
             ...
             string data = await api.GetInformationAsync();
             ...                   
        }
    }

MainPageViewModel.cs VARIANT 2 = No loose coupling

    class MainPageViewModel
    {
        private IAnApi api = new AnApi();

        public async Task RetrieveData()
        {
             ...
             string data = await api.GetInformationAsync();
             ...                   
        }
    }

Aucun commentaire:

Enregistrer un commentaire