加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

dependency-injection – Dagger 2:如何在运行时更改提供的依赖

发布时间:2020-12-13 20:07:14 所属栏目:百科 来源:网络整理
导读:为了学习Dagger 2,我决定重写我的应用程序,但我仍然坚持为以下问题找到合适的解决方案. 出于这个例子的目的,让我们假设我们有一个名为Mode的接口: public interface Mode { Object1 obj1(); //some other methods providing objects for app} 和两个实现:
为了学习Dagger 2,我决定重写我的应用程序,但我仍然坚持为以下问题找到合适的解决方案.

出于这个例子的目的,让我们假设我们有一个名为Mode的接口:

public interface Mode {
    Object1 obj1();

    //some other methods providing objects for app
}

和两个实现:
NormalMode和DemoMode.

模式以单例存储,因此可以从应用程序内的任何位置访问.

public enum ModeManager {
  INSTANCE,;

  private Mode mode;

  public Mode mode() {
    if (mode == null)
      mode = new NormalMode();
    return mode;
  }

  public void mode(Mode mode) { //to switch modules at runtime
    this.mode = mode;
  }
}

NormalMode在运行时切换到DemoMode(假设,当用户在背景上点击几次时)

public void backgroundClicked5Times(){
  ModeManager.INSTANCE.mode(new DemoMode());
  //from now on every object that uses Mode will get Demo implementations,great!
}

首先,我摆脱了单例并将模式定义为Dagger 2模块:

@Module
public class NormalModeModule {
  @Provides
  public Object1 provideObject1() {
    return new NormalObject1();
  }
}

@Module
public class DemoModeModule {
  @Provides
  public Object1 provideObject1() {
    return new DemoObject1();
  }
}

现在在方法backgroundClicked5Times中,而不是处理单例,我想用DAG中的DemoModeModule替换NormalModeModule,所以其他需要Object1的类从现在开始将获得DemoObject1实现.

我怎么能在Dagger那样做?

提前致谢.

经过一段时间的匕首试验,我想出了一个似乎在我的用例中运行良好的解决方案.

>定义将保存有关模式的状态信息的类

public class Conf {
  public Mode mode;

  public Conf(Mode mode) {
    this.mode = mode;
  }

  public enum Mode {
    NORMAL,DEMO
  }
}

>在模块中提供Conf的单例实例

@Module
public class ConfModule {
  @Provides
  @Singleton
  Conf provideConf() {
    return new Conf(Conf.Mode.NORMAL);
  }
}

>将模块添加到AppComponent

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

>定义基于模式提供不同对象的模块

@Module
public class Object1Module {

  @Provides
  Object1 provideObject1(Conf conf) {
    if (conf.mode == Conf.Mode.NORMAL)
      return new NormalObject1();
    else
      return new DemoObject1();
  }
}

>要在运行时切换模式,只需注入Conf对象并进行修改:

public class MyActivity extends Activity {
    @Inject Conf conf;

    //...

    public void backgroundClicked5Times(){
        conf.mode = Conf.Mode.DEMO;

        //if you have dagger objects in this class that depend on Mode
        //execute inject() once more to refresh them
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读