17

I want to make a binding using a method annotated with @Provides into an eager singleton. I've found bug 216, which suggests this isn't possible, but doesn't mention the @Provides annotation explicitly.

I currently have a class that requests the eager singletons in time by itself being a singleton, but it's not a very nice solution.

public class LogicModule extends AbstractModule {
    @Override public void configure() {
        bind(SomeDep.class);
        bind(MyWorkaround.class).asEagerSingleton();
    }

    // cannot add eager requirement here
    @Provides @Singleton Logic createLogic(SomeDep dep) {
        return LogicCreator.create(dep);
    }

    private static class MyWorkaround {
        @Inject Logic logic;
    }
}

Can I change something near the comment that would make the workaround class obsolete?

blackpanther
  • 10,998
  • 11
  • 48
  • 78
Jorn
  • 20,612
  • 18
  • 79
  • 126
  • 1
    In the bug report you linked, "provider methods" means "methods annotated with @Provides". So you're right, it's not directly possible. But comment #11 on that bug report shows a better workaround than yours IMO (use a Provider<> instead). – Tavian Barnes Mar 03 '14 at 20:24

1 Answers1

18

Why not to use

bind(Logic.class).toInstance(LogicCreator.create(dep)); 
//ohh we missing dep

then we can do this

class LogicProvider implements Provider<Logic> {

    private final SomeDep dep;

    @Inject
    public LogicProvider(SomeDep dep) {
      this.dep = dep;
    }

    @Override
    public Logic get() {
      return LogicCreator.create(dep);
    }

}

and then

bind(Logic.class).toProvider(LogicProvider.class).asEagerSingleton();

You can even pass SomeDep dep to your provider as Provider<SomeDep> and then call providerDep.get() in LogicCreator.create() that would be a bit more robust.

Ben McCann
  • 18,548
  • 25
  • 83
  • 101
Milan Baran
  • 4,133
  • 2
  • 32
  • 49