1
votes

I have a singleton scoped class that needs access to a filename string that is only determined downstream in a narrower scope. The usual solution is to inject a provider into the singleton scoped class and call provider.get() when it’s actually time to get the narrower scoped object. In this case, however, the narrower scoped object is simply a string, which means I need to use a binding annotation to differentiate it from every other string. Two questions:

  1. Can a binding annotation be applied to an injected provider just like any other injected object?

  2. Do you agree that it’s better to just inject the filename string, which is all the singleton scoped class really needs to know about, or should I just take the simpler approach, which is to inject the object within which the filename string is contained (and accessible via a getter)? What I don’t like about the latter approach is that the singleton class has access to all kinds of stuff it doesn’t care about, which seems like it might make some folks weep.

Thanks!

1

1 Answers

2
votes
  1. Yes, binding annotations on Providers should work. The Key within Guice is an (annotation, type) tuple, whether represented as @Foo Bar or @Foo Provider<Bar>.

  2. Given the choice, I would probably just inject the String instance, because that's all you need. It may be a little weird to see @Filename Provider<String> but as long as you and your co-maintainers understand it, it's the most eloquent way to represent this in Guice.

Do be careful that you're not turning your design inside-out to accommodate Guice. Before injecting a @Filename Provider<String> into a @Singleton class FileSaver, make sure it wouldn't be easier to have FileSaver take no narrowly-scoped dependencies at all, and put the filename in as a parameter to your save or load method instead. :)