主要构造函数的Kotlin Dagger2错误

时间:2019-12-10 17:59:04

标签: android kotlin dependency-injection dagger-2

我正在尝试动手学习匕首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();
    }
}

2 个答案:

答案 0 :(得分:1)

请将汽车类别更新为

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

答案 1 :(得分:0)

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

在Java实现中,注入的是构造函数的声明中的变量,而不是car对象的属性。注入过程与您的类的属性无关。您可以通过使用注入的数据来设置类的属性。无论属性是私有属性还是公共属性,由于您在类对象的内部进行工作,因此始终可以执行设置过程。

将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 来喷射引擎车轮。为了使喷射器类能够设置属性,该属性必须是公共的。 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
}