Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid adding of inject method for each view?

Currently to get instance of for example Picasso in an activity, I need to add inject method to AppComponent. How to avoid adding of the inject method, because I have a lot of fragments and views where it should be injected:

AppComponent.class:

@ForApplication
@Singleton
@Component(
        modules = {AppModule.class,OkHttpClientModule.class,NetworkApiModule.class,NetworkAuthModule.class})
public interface AppComponent {
    void inject(Fragment1 obj);
    void inject(Fragment2 obj);
    void inject(Fragment3 obj);
    void inject(Fragment4 obj);    
    void inject(Fragment5 obj);    
    void inject(Fragment6 obj);
    ...
    }

Fragment1.class

public class Fragment1 extends Fragment {
    @Inject Picasso mPicasso;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyApplication.getComponent(getContext()).inject(this);
    }
}

My classes :

AppModule.class:

@Module
public class AppModule {
    private MyApplication mApplication;

    public AppModule(@NonNull MyApplication mApplication) {
        this.mApplication = mApplication;
    }

    @Provides
    @NonNull
    @Singleton
    public Application provideApplication() {
        return mApplication;
    }


   @Provides
   @ForApplication
    Context provideContext(){
        return mApplication;
    }

    @Provides
    @Singleton
    Picasso providesPicasso(@ForApplication Context context) {
        return new Picasso.Builder(context).build();
    }
}

ForApplication.class:

@Scope
@Retention(RUNTIME)
public @interface ForApplication {
}

MyApplication.class

public class MyApplicationextends Application {
    static Context mContext;
    private AppComponent component;
    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;

        setupComponent();
    }

    private void setupComponent() {
        component = DaggerAppComponent.builder().appModule(new AppModule(this)).build();
        component.inject(this);
    }

    public AppComponent getComponent() {
        if (component==null)
            setupComponent();
        return component;
    }



public static AppComponent getComponent(Context context) {
        return ((MyApplication) context.getApplicationContext()).getComponent();
    }

UPDATE

I want also inject adapters for fragments, and if I'll add inject to BaseFragment then BaseFragment will have all adapters for all child fragments

like image 347
NickUnuchek Avatar asked Sep 12 '16 09:09

NickUnuchek


1 Answers

One solution would be to use inheritance for the injection.

Just define a BaseFragment with a @Inject Picasso instance, create a injection method in your DaggerComponent for this BaseFragment and call it in the onCreate method of the BaseFragment. The more specific Fragments like Fragment1, 2.. can inherit from this BaseFragment and use the Picasso instance.

like image 167
Jacob Avatar answered Oct 08 '22 22:10

Jacob