Dagger 2: используйте Component.Builder в компоненте с несколькими зависимостями модулей - PullRequest
0 голосов
/ 10 апреля 2019

Я не могу понять, как правильно вводить Context, когда у меня есть компонент с несколькими зависимостями модулей, и я хочу использовать аннотацию 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);
}

Следующие объекты являются конструкторами PaymentPи VehicleProvider:

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

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

Им требуется база данных AppDatabase, предоставляемая в классе ApplicationModule.Для AppDatabase требуется контекст, который снова предоставляется в ApplicationComponent с использованием Component.Builder

. Этот код работает правильно, когда мне нужно использовать mainFragmentViewModelFactory, я просто вызываю

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

Однако яЯ не уверен, что сделал правильные шаги, так как в ViewModelModule я снова запросил зависимость Context, но он уже предоставлен в ApplicationModule.Я сделал правильные шаги?Вместо того, чтобы снова создавать контекст BindsInstance в ViewModelComponent, я могу использовать тот, который находится в ApplicationModule?

...