0

I'm trying to override a couple of injections for testing with a specific test module. This works fine as is for real singletons like so:

...custom module...
bind(SomeClass.class).toInstance(instanceOfMockedClass);
...

Now this imposes problems when ContextSingletons need to be overwritten. Doing the same like above obviously injects the same instance for all contexts (services, activities), where a separate instance would have been correct. I tried to wrap my head around the ContextScopedProvider but couldn't find a way to actually use this in a bind(...).toProvider(...) construct, as this class itself does not implement Guice's Provider<T> interface.

How can this be achieved?

(also asked on https://groups.google.com/forum/?fromgroups=#!topic/roboguice/MnWGrHFDOsQ)

Thomas Keller
  • 5,933
  • 6
  • 48
  • 80

1 Answers1

1

An alternate way to write that for a regular singleton would be something like this

bind(SomeClass.class).toProvider(SomeClassProvider.class).in(Singleton.class);

If you do it that way, you don't need to have the instance available at the time of the binding, which while fine for a Singleton, obviously won't work for a ContextSingleton since there's no context yet.

You can use the same kind of binding for a ContextSingleton:

bind(SomeClass.class).toProvider(SomeClassProvider.class).in(ContextSingleton.class);

Now, all the instances of SomeClass that RoboGuice injects for you will be properly scoped, whether Singleton or ContextSingleton.

emmby
  • 99,783
  • 65
  • 191
  • 249
  • Now, the problem is that I need to determine for what context the injection is triggered. My use case is that I have a service and an activity that should both inject roboguice's EventManager (which I want to override for different reasons). So I need to ensure that I have exactly one overriden instance for each context available, otherwise the event mechanism between the components would no longer work (if each component gets its own instance) or events I throw in the activity context also reach the service context, which is something I don't want. – Thomas Keller Apr 22 '13 at 07:57
  • As long as you bind each instance of your overridden EventManager using a ContextSingleton, each context should get its own EventManager. Be aware: if you're mixing bindings and annotations, bindings will always take precedence and annotations will be ignored. So if you have a @ContextSingleton annotation but you write a `bind(X.class).toProvider(Y.class);`, X will NO LONGER be a ContextSingleton, even though it has a @ContextSingleton annotation. – emmby Apr 22 '13 at 10:11
  • So are you saying that `bind(SomeClass.class).toProvider(SomeClassProvider.class).in(ContextSingleton.class);` should exactly do the magic, i.e. it only lets `SomeClassProvider` create one instance per `Context`? If yes, then this is the answer I'm looking for :) – Thomas Keller Apr 23 '13 at 06:56