0

I need to choose correct implementation of LocationProvider at a runtime. Both GoogleLocationService and AndroidLocationService have their own dependencies.

public interface LocationProvider{
   Observable<Location> getLocationProvider(Looper looper);
}

@ActivityScope
public class GoogleLocationService implements LocationProvider{

   ...

   @Inject
   public GoogleLocationService (...){
   }

}

@ActivityScope
public class AndroidLocationService implements LocationProvider{

   ...

   @Inject
   public AndroidLocationService (...){
   }

}

@ActivityScope   
public class LocationControl{

   LocationProvider locationProvider;

   @Inject
   public LocationControl(...){
      ...
   }

   public void start(){
      if(isGooglePlayServiceAvailable){
         locationProvider = new GoogleLocationService(...);
      } else {
         locationProvider = new AndroidLocationService(...);
      }
   }
}

What's the best approach to satisfy those dependencies using Dagger 2? Should i use lazy injections?

@ActivityScope   
public class LocationControl{

    @Inject
    Lazy<AndroidLocationService> androidlocationService;
    @Inject
    Lazy<GoogleLocationService> googlelocationService;

    LocationProvider locationProvider;

    @Inject
    public LocationControl(...){
       ...
    }

    public void start(){
       if(isGooglePlayServiceAvailable){
          locationProvider = googlelocationService.get();
       } else {
          locationProvider = androidLocationService.get();
       }
    }
 }

Or a factory?

@ActivityScope   
public class LocationControl{

   private final LocationProviderFactory locationProviderFactory;

   LocationProvider locationProvider;

   @Inject
   public LocationControl(LocationProviderFactory locationProviderFactory){
      this.locationProviderFactory = locationProviderFactory;
   }

   public void start(){
      if(isGooglePlayServiceAvailable){
         locationProvider = locationProviderFactory.getLocationProvider(google);
      } else {
         locationProvider = locationProviderFactory.getLocationProvider(android);
      }
   }
}

@ActivityScope
public class LocationProviderFactory{

   private final GoogleLocationService GoogleLocationService;
   private final AndroidLocationService AndroidLocationService;

   @Inject
   public LocationProviderFactory(GoogleLocationService googleLocationService, AndroidLocationService androidLocationService){
      this.googleLocationService = googleLocationService;
      this.androidLocationService = androidLocationService;
   }

   public LocationProvider getLocationProvider(condition){
       if(condition){
          return googleLocationService;
       } else {
          return androidLocationService;
       }
   }
}

Or maybe there is a better way?

sheddar
  • 270
  • 1
  • 4
  • 16
  • I've answered [a similar question here](https://stackoverflow.com/q/48874448/1426891); that question has Modules in the title, but since Dagger doesn't let you select between Modules at runtime, it talks about factory-based and `@Provides`-based switching. Marking as a dupe; please confirm if my answer there solves your problem, or edit your question if you're solving a different problem. Thanks! – Jeff Bowman Sep 07 '18 at 21:17
  • 1
    Possible duplicate of [Dagger2 - How to conditionally choose modules at runtime](https://stackoverflow.com/questions/48874448/dagger2-how-to-conditionally-choose-modules-at-runtime) – Jeff Bowman Sep 07 '18 at 21:17

0 Answers0