Search code examples
javadependency-injectionguice

Java Guice Named Bindings with Objects provided from other modules


Heres my current setup

Class file

public class ToyAdapter {

private final ToyClient toyClient;
private final Retryer retryer;

    @Inject
    public APIAdapter(final ToyClient toyClient,
                        @Named("toyRetryer") final Retryer retryer) {
        this.toyClient = toyClient;
        this.retryer = retryer;
    }

Guice file
I have several guice modules, but this one pertains to the above class

public class ToyModule extends AbstractModule {

    @Override
    protected void configure() {

        bind(ToyAdapter.class).in(Singleton.class);
        bind(Retryer.class).annotatedWith(Names.named("toyRetryer")).toInstance(getToyRetryer());
    }

    @Provides
    @Singleton
    public ToyClient getToyClient(...){
       ...
    }

    private Retryer getToyRetryer() {#Takes no arguments
        return RetryerBuilder...build();
    }
}

So far this works great! However, now my retryer requires a LogPublisher object provided in another module.

I'm trying

public class ToyModule extends AbstractModule {

    LogPublisher logPublisher;

    @Override
    protected void configure() {
        requestInjection(logPublisher);
        bind(ToyAdapter.class).in(Singleton.class);
        bind(Retryer.class).annotatedWith(Names.named("toyRetryer")).toInstance(getToyRetryer());
    }
    
    private Retryer getToyRetryer() {
        return RetryerBuilder.withLogPublisher(logPublisher).build();
    }
}

LogPublisher is provided in another guice module which has alot of other objects that depend on LogPublisher so I'd rather not just merge everything into one giant guice module.

@Provides
@Singleton
public LogPublisher getLogPublisher() {...}

Is this the proper way to do this? I'm getting Java findBugs errors saying unwritten field so I'm thinking I'm doing it wrong.


Solution

  • Declare your Retryer with help of @Provides/@Named annotations.

        @Provides
        @Singleton
        @Named("toyRetryer")
        public Retryer getToyRetryer(LogPublisher logPublisher) {
            return RetryerBuilder.withLogPublisher(logPublisher).build();
        }