Search code examples
dependency-injectionguice

What is the difference between injection through the constructor and injection through field annotations with Guice?


I have the below code to do dependency injection using Guice. The first one is using constructor injection while the other one is adding @Inject directly above the field. Is there any difference between these two ways? It seems that constructor injection is recommended on the Guice official website.

class BillingService {
    private final CreditCardProcessor processor;
    private final TransactionLog transactionLog;

    @Inject
    BillingService(CreditCardProcessor processor, TransactionLog transactionLog) {
        this.processor = processor;
        this.transactionLog = transactionLog;
    }
    ...
}

And:

class BillingService {
    @Inject
    private final CreditCardProcessor processor;
    @Inject
    private final TransactionLog transactionLog;
    BillingService() {

    }
    ...       
}

Solution

  • The differences I would point:

    • without constructor injection you won't be able to use the final modifier, i.e. your code above won't compile. Commenting the advantages of final members is off-topic here.
    • with constructor injection all dependencies are kind of mandatory. You won't be able to instantiate the class without knowing about each declared dependency.
    • writing test cases with constructor injection might be easier (see the answer of The111).
    • there is another type of DI - setter injection - which can be more naturally mixed with constructor injection (e.g. for separating mandatory and optional dependencies).