匕首2:如何在运行时更改提供的依赖项 [英] Dagger 2: how to change provided dependencies at runtime

查看:69
本文介绍了匕首2:如何在运行时更改提供的依赖项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了学习Dagger 2,我决定重写我的应用程序,但我坚持为以下问题寻找合适的解决方案。

In order to learn Dagger 2 i decided to rewrite my application but I'm stuck with finding the proper solution for the following problem.

为此假设我们有一个名为 Mode 的接口:

For the purpose of this example let's assume we have an interface called Mode:

public interface Mode {
    Object1 obj1();

    //some other methods providing objects for app
}

和两个实现:
NormalMode DemoMode

Mode存储在单例中,因此可以从应用程序中的任何位置进行访问。

Mode is stored in singleton so it could be accessed from anywhere within application.

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 (比方说,当用户两次在后台单击Clickcs时)

The NormalMode is switched to DemoMode at runtime (let's say, when user clickcs on background couple of times)

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






所以首先我摆脱了单例并定义为Dagger 2模块的模式:


So first I got rid of the singleton and defined Modes as Dagger 2 modules:

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

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

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

Now in the method backgroundClicked5Times instead of dealing with singleton I would like to replace NormalModeModule with DemoModeModule in DAG so the other classes that need Object1 would get a DemoObject1 implementation from now on.

如何在Dagger中做到这一点?

How can I do that in Dagger?

预先感谢。

推荐答案

也许您可以考虑使用多重绑定?

Maybe you can consider using multibindings?

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

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

以及使用模式时:

@Inject
Map<String, Mode> modes;
//or you perfer lazy initialization:
Map<String, Provider<Mode>> modes;

public void backgroundClicked5Times(){
  ModeManager.INSTANCE.mode(modes.get("demo"));
  //if you are using Provider:
  ModeManager.INSTANCE.mode(modes.get("demo").get());
  //from now on every object that uses Mode will get Demo implementations, great!
}

这篇关于匕首2:如何在运行时更改提供的依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆