Android Dagger 和任意时刻设置模块

Android Dagger and setting a module at arbitrary moment

我是使用 Dagger 和 DI 的新手。我正在尝试使用 AndroidInjection 解析器将依赖项注入其 activity.

的片段中

一般来说,我的理解是,在使用 Dagger.android 的情况下,我必须创建 MyAppComponent 并安装 AndroidInjectionModule 才能使用 AndroidInjection.inject(Activity/Fragment/etc..)。通过这种方式,我提供了Subcomponents与Builder的接口,让Dagger能够生成合适的注入器。

但是如果我有子组件,即依赖于带参数化构造函数的模块的 DeviceFragmentSubcomponent 怎么办?

@Subcomponent(modules = {DeviceModule.class})
public interface DevicePageFragmentSubcomponent extends AndroidInjector<DevicePageFragment>{

    @Subcomponent.Builder
    public abstract class Builder extends AndroidInjector.Builder<DevicePageFragment>{
        public abstract Builder setDeviceModule(DeviceModule deviceModule);
    }
}

@Module
public class DeviceModule {

    private Device mDevice;

    public DeviceModule(Device device) {
        mDevice = device;
    }

    @Provides
    public Device provideDevice(){
        return mDevice;
    }
}

在 DeviceActivity 中设置 DeviceModule 实例以便在其片段中使用 AndroidInjection.inject(this) 应该做什么?

是否可以在创建应用程序的依赖树时而不是在任意事件中添加所需的模块?

Dagger 的 Android 注入部分(目前)只能与 AndroidInjection.inject(this) 一起使用,它将使用预定义模块注入给定的 Android 框架类型。

因此,无法传入参数或模块。

您的第一个选择是不使用 Dagger 的 Android 注入部分。只需创建您认为合适的组件并注入您的对象即可。

第二个选项是不使用参数/模块。理论上,如果你的 Activity 可以创建一个 DeviceModule,那么 Dagger 也可以,因为它可以访问 Activity——并且通过使用 Android 注入部件,组件注入您的类型可以访问它。

您没有指定 Device 有什么依赖项或为什么需要将它从您的片段传递给 DeviceModule

假设您的 Device 取决于 DevicePageFragment

class Device {
  @Inject Device(DevicePageFragment fragment) { /**/ } // inject the fragment directly
}

您可以访问该片段并做您想做的事。如果这不是你的情况,假设你需要阅读参数 Bundle。您可以修改您的模块,使其不使用设备,而是自己创建它,并去掉构造函数参数。

@Module
public class DeviceModule {

  // no constructor, we create the object below

  // again we take the fragment as dependency, so we have full access
  @Provides
  public Device provideDevice(DevicePageFragment fragment){
    // read your configuration from the fragment, w/e
    long id = fragment.getArguments().getLong("id")
    // create the device in the module
    return new Device(id);
  }
}

最后这真的取决于你的用例。


我试图展示的是您可以访问您尝试注入的对象。这意味着无论你能在这个对象中做什么,你都可以在 Dagger 中做。不需要参数化模块,因为您可以从目标中提取这些参数,如上所示。