这是在 Dagger 2 中向构造函数添加参数的正确方法吗?
Is this the correct way of adding parammeters to constructor in 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");
}
}
根据一些教程,我创建了几个模块 类:
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(modules = {ClientModule.class})
public interface ClientComponent {
Client provideClient();
}
这很好用。从我的 activity 我可以执行以下操作并且有效:
ClientComponent clientComp = DaggerClientComponent
.builder()
.clientModule(new ClientModule())
.build();
Client client = clientComp.provideClient();
client.work();
问题
我了解如何在客户端中注入依赖项(至少我是这么认为的)。但是我如何将参数添加到 client/dependency?
的构造函数中
我的意思是,如果我想向我的对象添加一些 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 原则?
有两种基本方法可以让 Dagger 提供一个 class:
的实例
将 @Inject
添加到构造函数,并将 class 的依赖项作为构造函数参数放入。
将 @Provides
注释的方法添加到 @Module
注释的 class,并将该模块安装到您的 @Component
.
每个 class 您只需要使用一种方法。因此,在您的第一个示例中, Client
和 Dependency
可以正常使用;你不需要 ClientModule
和 DependencyModule
.
添加 int
依赖项后,现在您确实需要一个模块,因为没有 class 到 @Inject
。该模块只需要提供 int
,这样就可以了:
@Module
public class ClientIdModule {
private final clientId;
public ClientIdModule(int clientId) {
this.clientId = clientId;
}
@Provides
static int clientId() {
return clientId;
}
}
现在,如果您将 ClientIdModule
安装到您的组件中,您将能够获得具有正确 ID 的 Client
,它的 Dependency
也将如此。
上下文
最近我开始研究依赖注入和 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");
}
}
根据一些教程,我创建了几个模块 类:
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(modules = {ClientModule.class})
public interface ClientComponent {
Client provideClient();
}
这很好用。从我的 activity 我可以执行以下操作并且有效:
ClientComponent clientComp = DaggerClientComponent
.builder()
.clientModule(new ClientModule())
.build();
Client client = clientComp.provideClient();
client.work();
问题
我了解如何在客户端中注入依赖项(至少我是这么认为的)。但是我如何将参数添加到 client/dependency?
的构造函数中我的意思是,如果我想向我的对象添加一些 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 原则?
有两种基本方法可以让 Dagger 提供一个 class:
的实例将
@Inject
添加到构造函数,并将 class 的依赖项作为构造函数参数放入。将
@Provides
注释的方法添加到@Module
注释的 class,并将该模块安装到您的@Component
.
每个 class 您只需要使用一种方法。因此,在您的第一个示例中, Client
和 Dependency
可以正常使用;你不需要 ClientModule
和 DependencyModule
.
添加 int
依赖项后,现在您确实需要一个模块,因为没有 class 到 @Inject
。该模块只需要提供 int
,这样就可以了:
@Module
public class ClientIdModule {
private final clientId;
public ClientIdModule(int clientId) {
this.clientId = clientId;
}
@Provides
static int clientId() {
return clientId;
}
}
现在,如果您将 ClientIdModule
安装到您的组件中,您将能够获得具有正确 ID 的 Client
,它的 Dependency
也将如此。