主构造函数的 Kotlin Dagger2 错误

Kotlin Dagger2 Error with Primary constructor

我正在尝试学习 dagger 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;
    }
}

Car.java class 有 2 个依赖项。

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

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

这是我的科特林代码:-

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();
    }
}

请将汽车 Class 更新为

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

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

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

而将 Kotlin class 定义为:

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 将生成注入器 class MembersInjector 来注入 enginewheel .要使注入器class能够设置属性,属性必须是public。 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.Constructor 注入。将 Kotlin class 定义为:

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

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

2.Field注射。将 Kotlin class 定义为:

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
}