0

I want to set a value to my sub-component builder at the time of building it. If simple Dagger 2 is concerned, we can achieve like following:

@UserScope
@Subcomponent(modules = {UserModule.class, ActivityBuilder.class, NewEditQuotationModule.class})

public interface UserComponent {
NewEditQuotationComponent.Builder getNewEditQuotationComponent();
void inject(UserManager userManager);

@Subcomponent.Builder
interface Builder {
    @BindsInstance
    Builder user(User user);

    UserComponent build();
}}

But In case of Dagger Android, Subcomponent and its associated builder is handled by @ContributesAndroidInjector. Dagger Auto generate Subcomponent and its builder even its implementation with the current context.

I want to set some value at the time of building My Dagger Android Subcomponent. I tried by following approach:

 @Subcomponent(modules = NewEditQuotationModule.class)
    public interface NewEditQuotationComponent extends AndroidInjector<InquiriesEditNewMainActivity> {


    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<InquiriesEditNewMainActivity> {
        @BindsInstance
        public abstract Builder setName(@Named("My_Name") String name);
    }}

        @Module
    public abstract class NewEditQuotationModule {
        @Binds
        @IntoMap
        @ActivityKey(InquiriesEditNewMainActivity.class)
        abstract AndroidInjector.Factory<? extends Activity>
        bindInquiriesEditNewMainActivityInjectorFactory(NewEditQuotationComponent.Builder builder);

    }

I tired to build it by following way:

AndroidInjector.Builder androidInjector = MyApplication
                .getApplication()
                .getAppComponent()
                .getApiEndPoint()
                .getApiEndPointComponent()
                .getUserManager()
                .getUserComponent()
                .getNewEditQuotationComponent().setName("My Name");
        androidInjector.seedInstance(this);
        androidInjector.build();

But not succeed. Please let me know

  1. How can I set some value at the time of building my component?
  2. Where am I wrong in the previous approach?
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Vinit Saxena
  • 683
  • 2
  • 11
  • 27
  • @JeffBowman : My scenario is, Some date is coming from previous Activity and the current activity is having 5 fragments and all of them need that data. So I want to provide that data by setting it in the activitie's component at the time of building it. Your suggested approach, I think will not work. Can you please help me out to solve the problem? – Vinit Saxena Jul 26 '18 at 18:01

1 Answers1

1

dagger.android works by automatically creating your component in onCreate, and needs to work this way because Android is allowed to create your Activity on its own. Pre-creating your AndroidInjector will not work; that is what's wrong with your previous approach.

As I tried to indicate through a duplicate-question vote, the only way for you to set module instance or @BindsInstance values in dagger.android is by overriding the seedInstance method in the AndroidInjector.Builder that serves as your @Subcomponent.Builder as well. This will let you pull values out of the Activity instance and set them in your Activity graph.

Though you could always stash data in a @Singleton (ApplicationComponent-scoped) object or VM global variable, you are trying to do the right thing by passing data carefully from Activity to Activity without setting global state. I think this is the right approach, but also that your solution probably will not involve constructing an AndroidInjector explicitly. Instead, pass your data through the extras bundle, which is an idiomatic way of transferring parameters and other data into Activities; you can then insert that data into your graph by pulling it out of getIntent().getExtras() on your Activity instance in seedInstance, since getIntent() should be populated by the time onCreate(Bundle) runs.

Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251