匕首2:在具有多个模块依赖项的组件中使用Component.Builder

时间:2019-04-10 07:34:26

标签: android dependency-injection dagger-2 builder dagger

当我有一个具有多个模块依赖项的组件并且想要使用Component.Builder注释时,我不明白如何正确地注入上下文。

我有一个应用程序模块:

@Module  
public class ApplicationModule {
    @Provides
    public AppDatabase provideDatabase(Context context){
        return AppDatabase.getInstance(context);
    }  
}

这是我的ApplicationComponent,在其中我使用了Component.Builder以便在依赖图上提供上下文:

@Singleton
@Component(modules =  { ApplicationModule.class } )
public interface ApplicationComponent {
   void inject(MainFragment mainFragment);

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder context(Context context);

        ApplicationComponent build();
    }
}

在我的自定义应用程序中,我使用以下代码来提供上下文:

appComponent = DaggerApplicationComponent.builder().context(getApplicationContext()).build();

然后我有另一个Dagger模块,用于提供ViewModelsFactory: ViewModelModule

@Module
public class ViewModelModule {

    @Singleton
    @Provides
    public MainFragmentViewModelFactory provideMainFragmentViewModelFactory(IVehicleProvider vehicleProvider, IPaymentProvider paymentProvider, IBackgroundOperationResponse response){
        return new MainFragmentViewModelFactory(vehicleProvider, paymentProvider, response);
    }
}

和相对的ViewModelComponent,在这里我再次使用了Component.Builder,如您所见,我在这里有三个模块:ViewModelModule,ApplicationModule和ProviderModule

@Singleton
@Component( modules = { ViewModelModule.class, ApplicationModule.class, ProviderModule.class })
public interface ViewModelComponent {
    MainFragmentViewModelFactory getMainFragmentViewModelFactory();

    @Component.Builder
    interface Builder{
        @BindsInstance
        Builder context(Context context);

        @BindsInstance
        Builder response(IBackgroundOperationResponse response);

        ViewModelComponent build();
    }
}

最后,由于MainFragmentViewModelFactory需要IVehicleProvider和IPaymentProvider,所以我有另一个模块: ProviderModule

@Module
public abstract class ProviderModule {

    @Singleton
    @Binds
    abstract IVehicleProvider bindVehicleProvider(VehicleProvider vehicleProvider);

    @Singleton
    @Binds
    abstract IPaymentProvider bindPaymentProvider(PaymentProvider paymentProvider);
}

以下是PaymentProvider和VehicleProvider的构造函数:

@Inject
public PaymentProvider(AppDatabase db){
    this.db = db;
}

@Inject
public VehicleProvider(AppDatabase db){
    this.db = db;
}

它们需要在ApplicationModule类上提供的AppDatabase。 AppDatabase要求使用Component.Builder

在ApplicationComponent中再次提供一个上下文。

当我需要使用mainFragmentViewModelFactory时,此代码可以正常工作

mainFragmentViewModelFactory = DaggerViewModelComponent
                .builder()
                .context(context)
                .response(this)
                .build()
                .getMainFragmentViewModelFactory();

但是,我不确定我是否执行了正确的步骤,因为在ViewModelModule中,我再次请求了Context依赖关系,但是ApplicationModule中已经提供了该依赖。我是否已执行正确的步骤?除了可以在ViewModelComponent中再次创建BindsInstance上下文之外,我还可以使用ApplicationModule中特权的那个吗?

0 个答案:

没有答案