Issues implementing Assisted Injection while using Dagger-2 and Autofactory

1.3k Views Asked by At

I am using Dagger-2 (ver: 2.7) and AutoFactory (ver: 1.0-beta3). I am facing a peculiar issue.

I have a a class MyRequest who's ctor takes 2 parameters as:

  1. ConnectivityManager conmgr
  2. int somevalue

I created the ctor as

@Autofactory
public MyRequest(@Provider ConnectivityManager conmgr, int somevalue){
//
}

I have a module containing the following

@Provides
@SystemScope
public final ConnectivityManager provideConnectivityManager(App app) {
return (ConnectivityManager)       
app.getSystemService(Context.CONNECTIVITY_SERVICE);
}

In the same module I do the following

@Provides
@SystemScope
public final MyRequestFactory providesMyRequestFactory(ConnectivityManager connectivityManager {
    return new MyRequestFactory(connectivityManager);
}

I am getting build error incompatible types: ConnectivityManager cannot be converted to Provider < ConnectivityManager >.

Any idea how to solve this ?

1

There are 1 best solutions below

3
On

As in the AutoFactory example, if your constructor takes a Foo, your AutoFactory's generated constructor will take a Provider<Foo> instead. This is so your factory will request a new Foo (or ConnectivityManager) once for each call to get without necessarily sharing instances between them.

It may be the case that you want Foo or ConnectivityManager to be the same instance for all instances of the created object (MyRequest here), but that's for you and Dagger to dictate, not AutoFactory. Consequently, AutoFactory will always generate code that takes Providers, whether you use them that way or not.

Luckily, the fix is very easy: Dagger can inject a Provider<ConnectivityManager> just as easily as it can inject a ConnectivityManager (as it can for any binding), so you can just change your @Provides method like so...

@Provides
@SystemScope
public final MyRequestFactory providesMyRequestFactory(
        Provider<ConnectivityManager> connectivityManagerProvider {
    return new MyRequestFactory(connectivityManagerProvider);
}

...but because your generated factory will have an @Inject annotation, you would probably be better off deleting the @Provides method entirely and letting Dagger use that constructor for MyRequestFactory injections. Though you'll lose the @SystemScope scope annotation from the @Provides method, that's no problem: With the Provider<ConnectivityManager> injection above, you don't have to worry about the lifecycle of the generated factory, so you can fall back to a default unscoped provision.