【问题标题】:Kotlin Dagger2 Error with Primary constructor主构造函数的 Kotlin Dagger2 错误
【发布时间】:2019-12-10 17:59:04
【问题描述】:

我正在尝试学习匕首 2,尝试将基本的 java 示例转换为 kotlin,但由于出现以下错误而无法这样做...

错误:Dagger 不支持注入私有字段 私有 com.example.Engine 引擎;

这是运行良好的 Java 代码,

public class Car {

    private Engine engine;
    private Wheel wheel;

    @Inject
    public Car(Engine engine, Wheel wheel) {
        this.engine = engine;
        this.wheel = wheel;
    }
}

具有 2 个依赖项的 Car.java 类。

public class Engine {
    @Inject
    Engine(){}
}

public class Wheel {
    @Inject
    Wheel(){}
}

这是我的 kotlin 代码:-

class Car(@Inject  var engine: Engine, @Inject  val wheels: Wheels) {
    fun drive(){
        Log.d("CAR","<<<<<< DRIVING >>>>>")
    }
}

class Engine @Inject constructor() {}

class Wheels @Inject constructor() {}

@Component
interface CarComponent {
    fun getCar() : Car
}

这是生成的代码

public final class Car {
    @org.jetbrains.annotations.NotNull()
    @javax.inject.Inject()
    private com.toi.roboelectric.Engine engine;
    @org.jetbrains.annotations.NotNull()
    @javax.inject.Inject()
    private final com.toi.roboelectric.Wheels wheels = null;

    public final void drive() {
    }

    @org.jetbrains.annotations.NotNull()
    public final com.toi.roboelectric.Engine getEngine() {
        return null;
    }

    public final void setEngine(@org.jetbrains.annotations.NotNull()
    com.toi.roboelectric.Engine p0) {
    }

    @org.jetbrains.annotations.NotNull()
    public final com.toi.roboelectric.Wheels getWheels() {
        return null;
    }

    public Car(@org.jetbrains.annotations.NotNull()
    com.toi.roboelectric.Engine engine, @org.jetbrains.annotations.NotNull()
    com.toi.roboelectric.Wheels wheels) {
        super();
    }
}

【问题讨论】:

    标签: android kotlin dependency-injection dagger-2


    【解决方案1】:

    请将汽车类更新为

    class Car @Inject constructor(var engine: Engine,val wheels: Wheels) {
    fun drive(){
        Log.d("CAR","<<<<<< DRIVING >>>>>")
    }
    

    【讨论】:

    • 嘿,您的解决方案有效,但这与私有无关。即使您删除私有,它也会起作用。我相信它是用“@Inject”注释,我把它放在变量级别。
    • 知道了。这是关于 @Inject 构造函数
    【解决方案2】:

    这个问题是关于如何在 Dagger 2 中将数据注入到一个对象中。在 Dagger 2 中有两种方法可以做到这一点。一种是通过类的构造函数注入,另一种是直接注入类的字段。

    在您的 Java 实现中,您注入的是构造函数声明中的变量,而不是汽车对象的属性。注入过程与您的类的属性无关。您可以使用注入的数据设置类的属性。无论属性是私有的还是公共的,设置过程总是可以完成的,因为您在类对象的内部工作。

    同时将 Kotlin 类定义为:

    class Car(@Inject  var engine: Engine, @Inject  val wheels: Wheels)
    

    如果我们检查这个 Kotlin 实现的 java 代码,我们可以看到这次构造函数除了 super()

    什么也没做
    public Car(@org.jetbrains.annotations.NotNull()
    com.toi.roboelectric.Engine engine, @org.jetbrains.annotations.NotNull()
    com.toi.roboelectric.Wheels wheels) {
        super();
    }
    

    这一次,注入程序是现场直接注入程序。在这种情况下,Dagger 将生成注入器类 MembersInjector 来注入 enginewheel。要使注入器类能够设置属性,该属性必须是公共的。 MembersInjector 将如下所示:

    public final class Car_MembersInjector implements MembersInjector<Car> {
    private final Provider<Engine> engineProvider;
    private final Provider<Wheel> wheelProvider;
    
    public Car_MembersInjector(Provider<Engine> engineProvider, Provider<Wheel> wheelProvider) {
        this.engineProvider = engineProvider;
        this.wheelProvider = wheelProvider;
    }
    
    public static MembersInjector<Car> create(Provider<Engine> engineProvider,
                                              Provider<Wheel> wheelProvider) {
        return new Car_MembersInjector(engineProvider, wheelProvider);
    }
    
    @InjectedFieldSignature("com.freddie.daggerkotlin.Car.engine")
    public static void injectEngine(Car instance, Engine engine) {
        instance.engine = engine;
    }
    
    @InjectedFieldSignature("com.freddie.daggerkotlin.Car.wheel")
    public static void injectWheel(Car instance, Wheel wheel) {
        instance.wheel = wheel;
    }
    
    @Override
    public void injectMembers(Car instance) {
        injectEngine(instance, engineProvider.get());
        injectWheel(instance, wheelProvider.get());
    }
    }
    

    这个问题有两种解决方案:

    1.构造函数注入。将 Kotlin 类定义为:

    class Car @Inject constructor(var engine: Engine, var wheel: Wheel)
    

    class Car @Inject constructor(var engine: Engine, var wheel: Wheel)
    

    2.字段注入。将 Kotlin 类定义为:

    class Car @Inject constructor()
    {
        @Inject lateinit var engine: Engine
        @Inject lateinit var wheel: Wheel
    }
    

    如果希望引擎和轮子是私有的,则只是私有修饰符:

    class Car @Inject constructor ()
    {
        private lateinit var engine: Engine
        private lateinit var wheel: Wheel
    }
    

    【讨论】:

      猜你喜欢
      • 2019-01-10
      • 1970-01-01
      • 1970-01-01
      • 2020-10-01
      • 1970-01-01
      • 2018-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多