Dagger2+Moxy+MVP架构下Repository实例创建方式咨询
嘿,你的感觉完全没错——在Activity中创建Repository再传递给Presenter确实是反模式,这违背了MVP架构的职责划分原则。咱们来一步步梳理正确的实现方式:
核心原则:让Dagger2把Repository直接注入到Presenter中
MVP架构里,View层(Activity)的职责只应该是展示UI、响应用户交互,绝对不该直接接触数据层的Repository。Presenter作为View和Model的中间协调者,才是应该持有Repository并调用其方法的角色。而Dagger2的核心作用就是管理这些依赖关系,所以我们要让Dagger自动把Repository注入到Presenter里,Presenter完全不用关心Repository是怎么创建的。
基于你现有代码的修改步骤
1. 确保Dagger能提供Repository实例
你的BudgetListRepository已经用@Inject标注了构造器,并且加了@Singleton注解,这很好——Dagger会自动识别这个构造器,结合你已经提供的BudgetDao实例,自动创建单例的BudgetListRepository。不需要额外在Module里写@Provides方法(当然如果有复杂创建逻辑可以加,但目前你的情况完全不需要)。
2. 修改Presenter,通过@Inject获取Repository
把Presenter改成依赖注入的方式获取Repository,而不是从Activity传入:
public class BudgetListPresenter extends MvpPresenter<BudgetListView> { private final BudgetListRepository budgetRepository; // 用@Inject标注构造器,让Dagger自动注入Repository依赖 @Inject public BudgetListPresenter(BudgetListRepository budgetRepository) { this.budgetRepository = budgetRepository; } // 示例:Presenter调用Repository加载数据 public void loadAllBudgets() { List<Budget> budgets = budgetRepository.getAll(); // 通过Moxy的ViewState更新UI getViewState().showBudgetsList(budgets); } // 其他业务方法同理,直接调用budgetRepository的方法即可 }
3. 在Activity中仅处理Presenter的注入,不碰Repository
Activity只需要注入Presenter并和Moxy绑定,完全不用关心Repository的存在:
public class BudgetsActivity extends MvpAppCompatActivity<BudgetListView, BudgetListPresenter> implements BudgetListView { @Inject BudgetListPresenter mPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_budgets); // 注入当前Activity,Dagger会自动完成Presenter及其依赖(Repository)的注入 ((MyApplication) getApplication()).getAppComponent().inject(this); // 绑定Moxy的Presenter setPresenter(mPresenter); } // 实现View层的回调方法,比如展示预算列表 @Override public void showBudgetsList(List<Budget> budgets) { // 更新RecyclerView或其他UI组件 } }
4. 确认AppComponent的配置正确
你现有的AppComponent已经包含了对BudgetListPresenter和BudgetsActivity的注入声明,这完全没问题。另外确保你的Application类正确初始化了AppComponent:
public class MyApplication extends Application { private AppComponent appComponent; @Override public void onCreate() { super.onCreate(); appComponent = DaggerAppComponent.builder() .appModule(new AppModule(this)) .build(); } public AppComponent getAppComponent() { return appComponent; } }
这么做的好处
- 符合MVP职责划分:View层彻底和数据层解耦,只专注UI;Presenter专注业务逻辑协调;Repository专注数据操作,各司其职。
- 便于单元测试:测试Presenter时,你可以轻松传入Mock的
BudgetListRepository,不用依赖真实的Room数据库。 - Dagger管理单例:因为
BudgetListRepository、BudgetDao、AppDataBase都是@Singleton,Dagger会保证整个应用中只有一个实例,避免资源浪费。
内容的提问来源于stack exchange,提问作者OhHiMark

