Search code examples
androidmvvmandroid-architecture-componentsandroid-livedataandroid-viewmodel

Is it correct to have a reference to a repository class in the view class when using MVVM?


In MyActivity, I'm trying to sign-in to a back-end server. This is what I have tried:

myViewModel = new ViewModelProvider(this, factory).get(MyViewModel.class);
myRepository = myViewModel.getMyRepository();

This is my view model class:

public class MyViewModel extends ViewModel {
    private MyRepository myRepository;

    @Inject
    MyViewModel(MyRepository myRepository) {
        this.myRepository= myRepository;
    }

    MyRepository getMyRepository() {
        return myRepository;
    }
}

And this is my repository class:

void signIn(Credential credential) {
    auth.signIn(credential).addOnCompleteListener(task -> {
        //Do stuff
    });
}

Is it correct to have a reference of my repository class in my activity class? Does this practice interfere with mvvm architecture pattern?


I'm asking this because I want to know if it's ok to keep a reference of repository in the activity class or only of the view model and create an object of the repository in the view model?


Solution

  • Your View should not have a reference to your Repository, as the architecture goes:

    View -> ViewModel -> Data/Model (Which, in this case is a repository)

    you're essentially making the ViewModel pointless, it's not going to format or change the data from the repository in any meaningful way with what you're doing (If anything, your viewmodel becomes more of a factory pattern) that processing will have to be done on the View now (which is incorrect for the architecture) because we try to achieve a "dumb" view, with as little as possible processing logic happening on a view, except for displaying data. With this method, you are also losing out on techniques such as LiveData; there's no way to observe onto LiveData in a ViewModel by returning the entire repository straight.

    Keep in mind this also somewhat breaks other architecture/OOP rules, as you are returning one entire repo with ALL methods available to the view, instead of only a few required methods.

    If you want to get a response back from your repository, look into:

    1. Returning an observable response from the repository to the viewmodel
    2. Implement callbacks from your repository to your viewmodel and have the viewmodel return these to the view

    There's no difference between doing this and injecting the repository straight into the View