Reputation: 27623
I'm not able to let MyClass
here being injected due to its Generic nature.
Dagger complains with this error:
Error:(187, 10) error: com.test.MyClass has type parameters, cannot members inject the raw type. via: com.test.MyComponent.inject(com.test.MyClass obj) [component injection method for type: com.test.MyClass]
I googled a bit but was unable to find a solution to this case scenario.
class MyClass<Type> {
@Inject
UserCredentials userCredentials;
ResultProducer<Type> mRP;
public MyClass(ResultProducer<Type> resultProd) {
mRP = resultProd;
Injector.getComponent().inject(this);
}
public Type getResult() {
if (userCredentials.isLoggedIn()) {
mRP.get();
} else {
mRP.getAnonymousCache();
}
}
}
@Component(modules = CredentialsModule.class )
interface MyComponent {
void inject(MyClass obj);
}
@Module
class CredentialsModule {
@Provides
public UserCredentials provideUserCredentials() {
return new UserCredentials();
}
}
Upvotes: 41
Views: 24353
Reputation: 1
You can use the next approach:
public interface MainComponent extends AndroidInjector<MainApplication> {
@NonNull
YourAwesomeClass getYourAwesomeClass();
}
public class MainApplication extends AxisApplication {
public static MainComponent mainComponent;
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
mainComponent = DaggerMainComponent
.builder()
.build();
mainComponent.inject(this);
return mainComponent;
}
MyAwesomeClass myAwesomeClass = MainApplication.mainComponent.getYouAwesomeClass()
Upvotes: 0
Reputation: 705
I solved this issue a bit differently, like so (we're 5 years further, so its in Kotlin, but i guess Java would work too):
// The class I want to inject, multiple generics
class SomeDataStorage<K, V> {
@Inject
lateinit var theDependencyINeed: TheDependencyINeed
init {
ComponentSingleton.getSomeComponent().inject(this as SomeDataStorage<Any, Any>)
}
fun getValue(key: K): V {
return theDependencyINeed.doSomeStuff() as V
}
}
// Component
interface MyComponent {
fun inject(someDataStorage: SomeDataStorage<Any, Any>)
}
The trick is to get some common parent of the generics you allow (in my case i dont care, so i just do Any, which is everything) and use that. Some unchecked casts are required, but thats OK.
Upvotes: 4
Reputation: 15046
For many will be useful to know, that it's allowed to inject fields into a generic class, without injecting the class itself.
It will be injected for you when a subclass is injected.
So you can have:
abstract class MyClass<? extends Something> {
@Inject UserCredentials userCredentials;
// you can use it further
}
class AnotherClass extends MyClass<Whatever> {
// just inject this one
}
Upvotes: 11
Reputation: 1019
You can use dagger2 without "inject".
Add method to your component:
@Component(modules = CredentialsModule.class )
interface MyComponent {
void inject(MyClass obj);
UserCredentials getUserCredentials();
}
And use it without any problems:
userCredentials=Injector.getComponent().getUserCredentials();
But this approach can be inconvenient if you have a lot of fields to inject
Upvotes: 6
Reputation: 11064
I have run into the same issue and found this article.
In a nutshell you have this options:
Upvotes: 53