将外部依赖的构造函数传递到Guice实现中

huangapple go评论77阅读模式
英文:

Passing constructors for outer dependency into Guice implementation

问题

我有一个工作,需要从深层存储中读取数据。我正在使用Guice DI来进行项目开发。

已经编写了一个深层存储,并且作为外部依赖项提供。我在实例化Guice中的客户端方面遇到了困难。

以下是代码示例:

JobModule

public class JobModule extends AbstractModule {
  private Config config;

  JobModule(Config config) {
     this.config = config;
  }

  @Override
  protected void configure() {
    bind(Reader.class).to(DeepStoreReader.class);
  }

  @Provides
  @Named("config")
  Config provideConfig() {
    return this.config;
  }
}

Reader 接口

public interface Reader {
  List<String> getData(String path);
}

DeepStoreReader

public class DeepStoreReader implements Reader {
  private final DeepStoreClient deepStoreClient;

  DeepStoreReader(@Named("config") Config config) {
     this.deepStoreClient = new DeepStoreClient(config);
  }

  @Override
  public List<String> getData(String path) {
    return this.deepStoreClient.getData(path);
  }
}

问题是我不想在 DeepStoreReader 构造函数内实例化 DeepStoreClient,因为这会使得测试 DeepStoreReader 变得困难,因为我将无法对 DeepStoreClient 进行模拟。

在这种情况下,实例化客户端的首选方式是什么?DeepStoreClient 不是一个 Guice 模块/实现,而是作为外部已发布的依赖项提供的。

PS:我对依赖注入不太熟悉,正在学习 Guice。

英文:

I have a Job, which should read data from deep storage. I am using Guice DI for my project.

There is a deep store already written and coming as an outer dependencie. I am struggling with instantiating the client in Guice

Here is the code

JobModule

public class JobModule extends AbstractModule {
  private Config config;

  JobModule(Config config) {
     this.config = config;
  }

  @Override
  protected void configure() {
    bind(Reader.class).to(DeepStoreReader.class);
  }

  @Provides
  @Named(&quot;config&quot;)
  Config provideConfig() {
    return this.config;
  }
}

Reader Interface

public interface Reader {
  List&lt;String&gt; getData(String path);
}

DeepStoreReader

public class DeepStoreReader implements Reader {
  private final DeepStoreClient deepStoreClient;

  DeepStoreReader(@Named(&quot;config&quot;) Config config) {
     this.deepStoreClient = new DeepStoreClient(config);
  }

  @Override
  public List&lt;String&gt; getData(String path) {
    return this.deepStoreClient.getData(path);
  }
}

The issue is I don't want to instantiate DeepStoreClient inside the DeepStoreReader constructor, because it becomes difficult to test DeepStoreReader, since I won't be able to mock DeepStoreClient

What is the preferred way to instantiate a client in such cases? DeepStoreClient is not a Guice module/implementation and is coming as an outer published dependency

PS: I am new to DI and learning Guice

答案1

得分: 1

你想要的是构造函数注入,例如:

@Inject
public DeepStoreReader(DeepStoreClient deepStoreClient) {
    this.deepStoreClient = deepStoreClient;
}

Guice 将会负责为你实例化 DeepStoreClient

编辑:

如果 DeepStoreClient 本身有依赖关系,你也可以注解那个构造函数:

@Inject
public DeepStoreClient(@Named("config") Config config) {
    // ... 8< ...
}
英文:

What you want is constructor injection, e.g.:

@Inject
public DeepStoreReader(DeepStoreClient deepStoreClient) {
    this.deepStoreClient = deepStoreClient;
}

Guice will take care of instantiating the DeepStoreClient for you.

EDIT:

If DeepStoreClient itself has dependencies, you can also annotate that constructor:

@Inject
public DeepStoreClient(@Named(&quot;config&quot;) Config config) {
    // ... 8&lt; ...
}

huangapple
  • 本文由 发表于 2020年9月15日 22:05:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/63903661.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定