【问题标题】:Dagger 2 injecting parameters of constructorDagger 2注入构造函数的参数
【发布时间】:2015-11-11 14:47:32
【问题描述】:

我在Dagger 2 website上看到了下面的例子:

class Thermosiphon implements Pump {
  private final Heater heater;

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

  ...
}

和文档:

当请求一个新的实例时,Dagger 会获取所需的 参数值并调用此构造函数。

当我编写一个模块来提供Thermosiphon 之类的

@Module
public class ThermosiphonModule {

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

}

Thermosiphon 构造函数仍然需要 Heater 作为参数,从而使整个“自动注入构造函数依赖项”变得无用。

我试过了

return new Thermosiphon(null); 

return new Thermosiphon(); 

(空构造函数)并希望 Dagger2 能够发现我希望注入缺失的 Heater,但提供的 Thermosiphon 的 Heater 始终为空;

我确认我的HeaterComponent / HeaterModule 工作正常并且能够提供Heater

我是否完全误解了“Dagger 为你满足构造函数依赖项”的整个功能,还是我遗漏了什么?

【问题讨论】:

    标签: android dagger-2


    【解决方案1】:

    如果您正在使用模块,那么如果您有两个提供程序模块绑定到同一个组件,那么您将能够允许它们将加热器视为构造函数参数。

    @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;
        }
    }
    

    但是通过构造函数注入,您还可以提供给定范围的对象,或无范围的对象,只要它们具有 @Inject 构造函数。

    例如,

    @Singleton
    @Component // no modules
    public interface SingletonComponent {
        Thermosiphon thermosiphon();
        Heater heater();
    
        void inject(Something something);
    }
    

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

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

    或者

    @Singleton
    public class Thermosiphon {
        @Inject
        Heater heater;
    
        @Inject
        public Thermosiphon() {
        }
    }
    

    【讨论】:

    • @EpicPandaForce 对不起,你能帮我解决这个问题吗? stackoverflow.com/q/43308649/6596724谢谢
    • 我的问题是:你能混合这两个依赖注入规则吗? class Usecase @Inject constructor(val restApi: RestService)class ViewModel{ lateinit var usecase : Usecase init{ Application.getRestComponent().inject(this) } }
    • 很好的帮助理解使用构造函数注入与使用模块的替代方式。
    【解决方案2】:

    首先,由于您已使用@Inject 注释Thermosiphon 的构造函数,因此您不需要@Provides 方法。 Dagger 在需要时使用此构造函数创建实例。只需使用 @Singleton 注释 Thermosiphon 类本身即可保留单例行为。

    如果您确实想使用@Provides 方法并完整回答您的问题,您可以将Heater 指定为该方法的参数:

    @Module
    public class ThermosiphonModule {
    
        @Provides
        @Singleton
        Thermosiphon provideThermosiphon(Heater heater) {
            return new Thermosiphon(heater);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-01
      • 2018-07-12
      • 2019-02-23
      • 1970-01-01
      • 2018-06-08
      • 2017-12-24
      • 2018-07-04
      相关资源
      最近更新 更多