Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger: Inject named string in constructor

I have a properties file and I would like to inject a property in a service.

I would like use the constructor method for DI like this:

@Inject
public ScanService(@Named("stocks.codes") String codes, IYahooService yahooService) {
    this.yahooService = yahooService;
    this.codes = codes;
}

I try to do a module like specified in this link => Dagger: Inject @Named strings?

@Provides
@Named("stocks.code")
public String providesStocksCode() {
    return "test";
}

And for the provider method for my service:

@Provides
@Singleton
public IScanService provideScanService(String codes, IYahooService yahooService){
    return new ScanService(codes, yahooService);
}

When I run the compilation I get this error:

[ERROR] /Users/stocks/src/main/java/net/modules/TestModule.java:[22,7] error: No injectable members on java.lang.String. Do you want to add an injectable constructor? required by provideScanService(java.lang.String,net.IYahooService) for net.modules.TestModule

How can I inject my property correctly in the constructor ?

Thanks.

like image 529
Kiva Avatar asked Jan 04 '15 17:01

Kiva


People also ask

What is @inject in constructor?

4.1. The @Inject annotation lets us define an injection point that is injected during bean instantiation. Injection can occur via three different mechanisms. Bean constructor parameter injection: public class Checkout { private final ShoppingCart cart; @Inject.

What does @inject do dagger?

Defining dependencies (object consumers) You use the @Inject annotation to define a dependency. If you annotate a constructor with @Inject , Dagger 2 can also use an instance of this object to fulfill dependencies. This was done to avoid the definition of lots of @Provides methods for these objects.

What is constructor injection in dagger?

inject. Inject annotation to identify which constructors and fields it is interested in. Use @Inject to annotate the constructor that Dagger should use to create instances of a class. When a new instance is requested, Dagger will obtain the required parameters values and invoke this constructor.

How do you inject an object into a dagger?

To inject an object in the activity, you'd use the appComponent defined in your Application class and call the inject() method, passing in an instance of the activity that requests injection. When using activities, inject Dagger in the activity's onCreate() method before calling super.


2 Answers

You have two different names: stocks.codes and stocks.code.

You will also have to annotate your provideScanService codes parameter:

@Provides
@Singleton
public IScanService provideScanService(@Named("stocks.codes") String codes, IYahooService yahooService){
    return new ScanService(codes, yahooService);
}

Or do it like this:

@Provides
@Singleton
public IScanService provideScanService(ScanService scanService){
    return scanService;
}
like image 159
nhaarman Avatar answered Feb 15 '23 22:02

nhaarman


If you mean Dagger 2, I can help you. First you have to declare dependencies in Component

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
    void inject(BaseActivity baseActivity);

    @Named("cloud") UserDataSource userCloudSource();
    @Named("disc") UserDataSource userDiscSource(); 
    UserDataRepository userDataRepository();  
}

then instantiate it in Module

@Module
public class ApplicationModule {

    @Provides @Named("cloud")
    UserDataSource provideCloudUserSource(UserCloudSource userSource) {
        return userSource;
    }

    @Provides @Named("disc")
    UserDataSource provideDiscUserSource(UserDiscSource userSource) {
        return userSource;
    }

    @Provides
    UserDataRepository provideUserRepository(UserDataRepository repository) {
        return repository;
    }

}

then inject it in constructor with @Named qualifiers

@Inject
public UserDataRepository(@Named("cloud") UserDataSource cloudSource, 
     @Named("disc") UserDataSource discSource) {
    this.cloudDataSource= cloudSource;
    this.discDataSource = discSource;
}
like image 39
voronnenok Avatar answered Feb 15 '23 23:02

voronnenok