Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
199 views
in Technique[技术] by (71.8m points)

android - Dagger 2 injecting parameters of constructor

I saw the following example on the Dagger 2 website:

class Thermosiphon implements Pump {
  private final Heater heater;

  @Inject
  Thermosiphon(Heater heater) {
    this.heater = heater;
  }

  ...
}

and the documentation:

When a new instance is requested, Dagger will obtain the required parameters values and invoke this constructor.

When I write a Module to provide a Thermosiphon like

@Module
public class ThermosiphonModule {

    @Provides
    @Singleton
    Thermosiphon provideThermosiphon() {
        return new Thermosiphon(???);
    }

}

the Thermosiphon constructor still requires a Heater as an argument, rendering the whole 'automatic injection of constructor dependencies' useless.

I tried

return new Thermosiphon(null); 

and

return new Thermosiphon(); 

(empty constructor) and hoped for Dagger2 to pick up that I wanted the missing Heater to be injected, yet the Heater of the provided Thermosiphon is always null;

I verified though my HeaterComponent / HeaterModule are working fine and are able to provide a Heater.

Do I completey misunderstand the whole feature of 'Dagger satisfies constructor dependencies for you' or am I missing something?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you're using modules, then if you have two provider modules bound to the same component, then you'll be able to allow them to see the heater as a constructor parameter.

@Module
public class HeaterModule {
    @Provides
    @Singleton
    Heater heater() {
        return new Heater(); // if not using @Inject constructor
    }
}

@Module
public class ThermosiphonModule {
    @Provides
    @Singleton
    Thermosiphon thermosiphon(Heater heater) {
        return new Thermosiphon(heater); // if not using @Inject constructor
    }
}

@Singleton
@Component(modules={ThermosiphonModule.class, HeaterModule.class})
public interface SingletonComponent {
    Thermosiphon thermosiphon();
    Heater heater();

    void inject(Something something);
}

public class CustomApplication extends Application {
    private SingletonComponent singletonComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        this.singletonComponent = DaggerSingletonComponent.builder().build(); //.create();
    }

    public SingletonComponent getSingletonComponent() {
        return singletonComponent;
    }
}

But with constructor injection, you will also be able to provide objects of that given scope, or unscoped objects, as long as they have a @Inject constructor.

For example,

@Singleton
@Component // no modules
public interface SingletonComponent {
    Thermosiphon thermosiphon();
    Heater heater();

    void inject(Something something);
}

And

@Singleton
public class Heater {
    @Inject
    public Heater() {
    }
}

And

@Singleton
public class Thermosiphon {
    private Heater heater;

    @Inject
    public Thermosiphon(Heater heater) {
        this.heater = heater;
    }
}

Or

@Singleton
public class Thermosiphon {
    @Inject
    Heater heater;

    @Inject
    public Thermosiphon() {
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...