首页 > 解决方案 > How can I use Repository

问题描述

I use Dagger2 and Moxy with MVP. As I understand, Presenter can call the Repository for loading and unloading data from the database. But I just can not figure out how to create an instance of the repository: in the Activity with the help of Dagger and transfer to the presenter or in the presenter itself?

I used Repository in Activity but I think it's an anti-pattern.

It provides Context

 @Module
 public class AppModule {
   private Context context;

   public AppModule(Context context){
       this.context = context;
   }

   @Singleton
   @Provides
   Context provideContext(){
       return context;
   }
 }

This module provides Room

 @Module
 public class RoomModule {
   @Singleton
   @Provides
   AppDataBase providesAppDataBase(Context context) {
     return Room.databaseBuilder(context, AppDataBase.class, "budget")
             .fallbackToDestructiveMigration()
             .allowMainThreadQueries()
             .build();
   }

@Singleton
@Provides
BudgetDao providesDao(AppDataBase database) {
    return database.getBudgetDao();
 }

 @Singleton
 @Provides
 DetailDao providesDetailDao(AppDataBase dataBase){
     return dataBase.getDetailDao();
 }
  }

AppComponent

@Singleton
@Component(modules = {RoomModule.class, AppModule.class})
public interface AppComponent {

void inject(BudgetListPresenter presenter);

void inject(BudgetsActivity activity);

void inject(DetailActivity activity);
 }

Repository.class

 @Singleton
 public class BudgetListRepository implements BudgetRepository {
 private BudgetDao budgetDao;

 @Inject
 public BudgetListRepository(BudgetDao budgetDao){
     this.budgetDao = budgetDao;
 }

 @Override
 public void updateBudget(Budget budget) {
     budgetDao.updateBudget(budget);
 }

 @Override
 public void addBudget(Budget budget) {
     budgetDao.insertBudget(budget);
 }

 @Override
 public void deleteBudget(Budget budget) {
     budgetDao.deleteBudget(budget);
 }

 @Override
 public Budget getBudget(String id) {
     return budgetDao.getBudget(id);
 }

 @Override
 public List<Budget> getAll() {
     return budgetDao.getAll();
 }
}

标签: androidrepositorymvppresenter

解决方案


The flow should be like this

First, you call a method from your view to your presenter.

Then, in your presenter, you need to communicate with any use case in your domain layer and that layer has the responsibility to inject the repository with dagger.

Let me show you an example

From your presenter, you inject your use case (interactor), this will be the responsable to communicate with the repository later

class LoginPresenter @Inject constructor(private val signInInteractor: SignInInteractor) : LoginContract.Presenter {
...

override fun signInWithEmailAndPassword(email: String, password: String) {
signInInteractor.signInWithEmailAndPassword(email, password)
...

Then your interactor should inject the repository like this

class SignInInteractorImpl @Inject constructor(val userRepository: UserRepository): SignInInteractor{
...

 override suspend fun pushUserIntoDatabase(account: GoogleSignInAccount): Unit = suspendCancellableCoroutine { continuation ->
        userRepository.createUser(account.displayName!!,account.email!!,object : UserRepository.UserRepositoryCallback{

            override fun onRemoteSuccess() {
                //success
            }

            override fun onRemoteFailure(errormsg:String) {
                //failure
            }

        })

    }

In this case I just use inside my use case a call to the repository to push data into Firebase

And in my PresentationModule I just inject that repo

 @Provides
    @Singleton
    fun provideUserRepositoryToLogin(userRepository: UserRepository): SignInInteractor {
        return SignInInteractorImpl(userRepository)
    }

This is the concept to follow

enter image description here


推荐阅读