Inject singleton inside RecyclerView.Adapter<RecyclerView.ViewHolder>

1,733 views
Skip to first unread message

Sebastian Riethmüller

unread,
May 31, 2016, 12:04:19 PM5/31/16
to Dagger Discuss
Hi guys,
I'm using dagger 2 in project. I provide an Singleton by a Dagger Modul:

@Module
public class MyModule{

   
private MySingleton mMySingleton ;

   
@Provides
    @Singleton
    MySingleton provideMySingelton() {
       
if (mMySingleton == null) {
           
mMySingleton = new MySingleton();
       
}
       
return mMySingleton ;
   
}
}

with this app component interface:

@Singleton
@Component(modules={MyModule.class})
public interface AppComponent {
   
void inject(MyFragment myFragment);
   
void inject(RecyclerView.Adapter recyclerViewAdapter);
}

The dagger components are building in my application class:

@Override
public void onCreate() {
super.onCreate();

// Dagger%COMPONENT_NAME%
mAppComponent = DaggerAppComponent.builder()
// list of modules that are part of this component need to be created here too
.myModule(new MyModule())
.build();
}

public static MyApp from(@NonNull Context context) {
return (MyApp) context.getApplicationContext();
}

I can inject my singleton in MyFragment:

@Inject protected MySingleton mMySingleton;

@Override
public void onCreate(Bundle savedInstanceState) {
MyApp.from(getContext()).getmAppComponent().inject(this);
}


But I can't inject it inside my RecyclerView.Adapter

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

@Inject protected MySingleton mMySingleton;

    @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

MyApp.from(context).getmAppComponent().inject(this);
}
}


In my MyAdapter is mMySingleton after run line  

    MyApp.from(context).getmAppComponent().inject(this);

always null.

Can somebody tell me why?
I understand it.

Much thanks

Ron Shapiro

unread,
May 31, 2016, 12:18:27 PM5/31/16
to dagger-...@googlegroups.com
Your inject method must take the concrete subclass that you want injected. In your case, a MembersInjector<RecyclerView.Adapter> has no idea how to inject into MyAdapter. Change the method to be void inject(MyAdapter adapter); and you should be good.

A couple asides:
  • Please don't do state management in your module unless you absolutely need to. Moreover, Dagger does this for you in ScopedProvider (which gets used when you use a scope on a provides method), so just return a new MySingleton from your module method and call it a day (or if you want, give it an @Inject constructor and annotate the class @Singleton).
  • Your module method can then be static, which generates a leaner component
  • Your Component builder doesn't need to take instances of components that have no-argument constructors. If all of your modules are like that, you can even call DaggerMyComponent.create() and Dagger will create any modules it needs by itself.

--
You received this message because you are subscribed to the Google Groups "Dagger Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dagger-discus...@googlegroups.com.
To post to this group, send email to dagger-...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages