1

I just started using Roboguice (+Guice) and I am not sure about the best practice how to use it.

In my Activity I have about 5 functions (out of about 30) which uses an object called "ProviderQueries" (Singleton). I could use it in two ways:

1.)

    protected void onResume() {
       super.onResume();
       getInjector().getInstance(ProviderQueries.class).setLanguage("EN");
}

2.)

class MyActivity extends RoboActivity {
    @Inject
    private ProviderQueries pv;

    ...

       protected void onResume() {
          super.onResume();
          pv.setLanguage("EN");
          }        
 }

1 - too long but the instance of ProviderQueries is used where it is needed
2 - short and nice but "pv" is available for the whole Activity but only needed in 5 different function...

Which approach would you use, or do you have a better solution?

Thanks in advance!

Mike Mitterer
  • 6,810
  • 4
  • 41
  • 62

2 Answers2

1

This is a bit of a judgement call. To me, 5 functions seems justification enough to put this in a member variable, which uses a cleaner syntax and reduces the explicit dependency on the injector. I see your point about it not being used in all 30 methods, but that seems of a secondary concern in my personal opinion (your own sense of aesthetics of course may be different).

If ProviderQueries is especially memory intensive, you may want to consider going with option 2 instead of 1 since option 1 will keep the object live for the duration of the activity. Not a consideration for most objects, but could be an issue for some.

If you weren't using Guice, how would you access your singleton? Presumably through an accessor method? You can, of course, always write your own accessor that performs #2 for you in a more compact way, although it won't bypass the small reflection overhead incurred for each access to the singleton.

emmby
  • 99,783
  • 65
  • 191
  • 249
  • I used ProviderQuery.getInstance() (PQ was implemented as Singleton-Factory before). ProviderQuery is just a helper class for Provider-Requests. My problem is mainly a design problem. Usually I try to keept the objects I need as close as possible to the function which uses them. – Mike Mitterer Aug 18 '11 at 15:00
0

Maybe you need to use Guice's Provider classes.

For an (simlpified) example from Guice site:

public class RealBillingService implements BillingService {
  private final Provider<CreditCardProcessor> processorProvider;

  @Inject
  public RealBillingService(Provider<CreditCardProcessor> processorProvider) {
    this.processorProvider = processorProvider;
  }

  public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {
    CreditCardProcessor processor = processorProvider.get();

    /* use the processor and transaction log here */
  }
}

Providers will hide the scope and are lightweight. They can be held in memory from the initial injection, but will not hold a reference to the concrete object you are using.

Documentation of this, with more examples: http://code.google.com/p/google-guice/wiki/InjectingProviders

Marcell
  • 973
  • 1
  • 6
  • 13