简体   繁体   中英

Dagger 2 How to solve constructor dependency

I am an Android developer and trying to learn Dagger2 . I have gone through some tutorials and got some basic understanding. I developed a basic java app using Dagger2 . And below is my app code.

Logger.java: Logger is simple java class which will print logs with some tag.

public class Logger {

    private String tag;

    @Inject
    public Logger(String tag) {
        this.tag = tag;
    }

    public void log(String msg) {
        System.out.println(tag + "::" + msg);
    }
}

InvertNumber.java: It will invert the passed number and prints log using Logger

public class InvertNumber {

    private Logger logger;

    @Inject
    public InvertNumber(Logger logger) {
        this.logger = logger;
    }

    public void invert(int i) {
        logger.log("Inverted value is " + (i * -1));
    }
}

Now I added Dagger2 depency classes (Module and component) like below

@Module
public class NumberModule {

    private String tag;

    public NumberModule(String tag) {
        this.tag = tag;
    }

    @Provides
    Logger provideLogger(){
        Logger logger = new Logger(tag);
        return logger;
    }

    @Provides
    InvertNumber provideTempManager(Logger logger){
        return new InvertNumber(logger);
    }
}

@Component(modules = NumberModule.class)
public interface NumberComponent {

    InvertNumber getInvertNumber();

}

Now below is my main method.

public static void main(String[] args) {

    NumberComponent numberComponent = DaggerNumberComponent.builder()
            .numberModule(new NumberModule("MyMain"))
            .build();

    InvertNumber invertNumber = numberComponent.getInvertNumber();

    invertNumber.invert(10);
}

To print logs in console, I have to provide tag to the logger . For this I am creating instance of NumberModule class and passing to NumberComponent builder.

Now my questions are:

  1. Is this correct way to pass tag using NumberModule instance
  2. If it is correct, according to DI concept, it is not encouraged to use new operator to create objects (new NumberModule())
  3. If the above code is wrong, what is the correct way?

Your way of solving problem is right, but there is one more using @Component.Buidler . (please, note that in your case @Inject annotation in Logger and InvertNumber constructor not working - you call them by hand).

Rewrite dagger stuff like that

@Module
public class NumberModule {
    @Inject
    public NumberModule() {}

    @Provides
    Logger provideLogger(@Named("logger_tag") String tag){
        Logger logger = new Logger(tag);
        return logger;
    }

    @Provides
    InvertNumber provideTempManager(Logger logger){
        return new InvertNumber(logger);
    }
}

@Component(modules = NumberModule.class)
public interface NumberComponent {

    InvertNumber getInvertNumber();

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder loggerTag(@Named("logger_tag") String tag);

        NumberComponent build();
    }
}

and use it

NumberComponent numberComponent = DaggerNumberComponent.builder()
            .loggerTag("MyMain")
            .build();

To allow dagger create Logger and InvertNumber for you (not manually calling their constructors), you need interfaces for each of them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM