这是在Dagger 2中向构造函数添加参数的正确方法吗?

时间:2015-10-19 09:46:07

标签: android dependency-injection dagger-2

上下文

最近我开始调查依赖注入和Dagger 2.它看起来是一个非常好的库,但对我来说似乎有点混乱。在某些情况下,我不确切知道如何继续。

我尝试了什么

我创建了一个简单的Android应用程序,可以创建客户端及其依赖项并执行一些(虚拟)工作。这些是类:

Client.java

public class Client {

    private Dependency dep;

    @Inject
    public Client(Dependency dep) {
        this.dep = dep;
    }

    public void work() {
        System.out.println("Client working");
        dep.doWork();
    }
}

Dependency.java

public class Dependency {

    @Inject
    public Dependency() {
    }

    public void doWork() {
        System.out.println("Dependency working");
    }
}

在一些教程之后,我创建了几个Module类:

DependencyModule.java

@Module
public class DependencyModule {

    @Provides
    Dependency provideDependency() {
        return new Dependency();
    }
}

ClientModule.java

@Module
public class ClientModule {

    @Provides
    Client provideClient(Dependency dep) {
        return new Client(dep);
    }

}

还有Component接口:

@Component(modules = {ClientModule.class})
public interface ClientComponent {

    Client provideClient();

}

这很好用。根据我的活动,我可以做以下工作:

ClientComponent clientComp = DaggerClientComponent
                .builder()
                .clientModule(new ClientModule())
                .build();

Client client = clientComp.provideClient();
client.work();

问题

我理解如何在客户端注入依赖项(至少我是这么认为的)。但是我如何将参数添加到客户端/依赖项的构造函数中?

我的意思是,如果我想在我的对象中添加一些int参数怎么办?像这样简单:

Client.java

public class Client {

    int id;
    Dependency dep;

    @Inject
    public Client(int id, Dependency dep) {
        this.id = id;
        this.dep = dep;
    }

    public void work() {
        System.out.println("id: " + id + " Client working");
        dep.doWork();
    }
}

Dependency.java

public class Dependency {

    private int id;

    @Inject
    public Dependency(int id) {
        this.id = id;
    }

    public void doWork() {
        System.out.println("id: " + id + " Dependency working");
    }
}

注意: 以下代码是我尝试过的。所以我不确定它的正确性。

因此,由于对象在其构造函数中具有新参数,因此模块必须更改:

DependencyModule.class

public class DependencyModule {

    @Provides
    Dependency provideDependency() {
        return new Dependency(id);
    }
}

ClientModule.class

@Module
public class ClientModule {

    @Provides
    Client provideClient(int id, Dependency dep) {
        return new Client(id, dep);
    }

}

问题

如何使用新模块?我还没有找到一种方法将id传递给那些方法。我让它工作的唯一方法是将它传递给Module构造函数并从provide方法中删除它。这样:

@Module
public class ClientModule {

    private int id;

    public ClientModule(int id) {
        this.id = id;
    }

    @Provides
    Client provideClient(Dependency dep) {
        return new Client(id, dep);
    }

}

DependencyModule.java中的方法相同。

这样,在ClientComponent接口中添加DependencyModule.class我可以这样做:

ClientComponent clientComp = DaggerClientComponent
                .builder()
                .clientModule(new ClientModule(clientId))
                .dependencyModule(new DependencyModule(dependencyId))
                .build();

Client client = clientComp.provideClient();
client.work();

这是正确的做法吗?

有没有更好的方法来获得相同的效果?

我是否违反DI原则?

1 个答案:

答案 0 :(得分:0)

有两种基本方法可以让Dagger提供类的实例:

  1. #version 400 core in vec4 VertPosition; in vec4 VertNormal; in vec4 VertColor; in vec4 VertTexture; uniform vec3 lightPos; void main() { float moment1 = gl_FragCoord.z; float moment2 = moment1 * moment1; gl_FragData[0] = vec4(moment1, moment2, 0.0, 1.0); } 添加到构造函数中,并将类的依赖项作为构造函数参数。

  2. @Inject - 带注释的方法添加到@Provides - 带注释的类中,然后将该模块安装到@Module

  3. 您只需为每个类使用一种方法。因此,在您的第一个示例中,@ComponentClient一样好;您还不需要DependencyClientModule

    添加DependencyModule依赖项后,现在需要一个模块,因为int没有类。该模块只需提供@Inject,所以这样的东西可以工作:

    int

    现在,如果您将@Module public class ClientIdModule { private final clientId; public ClientIdModule(int clientId) { this.clientId = clientId; } @Provides static int clientId() { return clientId; } } 安装到您的组件中,您将能够获得具有正确ID的ClientIdModule,并且其Client也是如此。