我正在努力解决一个特定的依赖注入问题,但我似乎无法弄清楚。仅供参考:我是 guice 新手,但我有其他 DI 框架的经验——这就是为什么我认为这不应该太复杂来实现。
我在做什么:我正在开发 Lagom 多模块项目并使用 Guice 作为 DI。
我想要实现的目标:向我的服务注入一些接口实现的多个命名实例(我们称之为发布者,因为它会将消息发布到 kafka 主题)。这个“发布者”已经注入了一些 Lagom 和 Akka 相关的服务(ServiceLocator、ActorSystem、Materializer 等)。
现在我想要两个这样的发布者实例,每个实例都会将消息发布到不同的主题(所以每个主题一个发布者实例)。
我将如何实现这一目标?我对同一主题的一个或多个实例没有问题,但是如果我想为每个实例注入不同的主题名称,我就有问题了。
所以我的发布者实现构造函数如下所示:
@Inject
public PublisherImpl(
@Named("topicName") String topic,
ServiceLocator serviceLocator,
ActorSystem actorSystem,
Materializer materializer,
ApplicationLifecycle applicationLifecycle) {
...
}
如果我想创建一个实例,我会在我的 ServiceModule 中这样做:
public class FeedListenerServiceModule extends AbstractModule implements ServiceGuiceSupport {
@Override
protected void configure() {
bindService(MyService.class, MyServiceImpl.class);
bindConstant().annotatedWith(Names.named("topicName")).to("topicOne");
bind(Publisher.class).annotatedWith(Names.named("publisherOne")).to(PublisherImpl.class);
}
}
我将如何为自己的主题绑定多个发布者?
我正在玩实现另一个私有模块:
public class PublisherModule extends PrivateModule {
private String publisherName;
private String topicName;
public PublisherModule(String publisherName, String topicName) {
this.publisherName = publisherName;
this.topicName = topicName;
}
@Override
protected void configure() {
bindConstant().annotatedWith(Names.named("topicName")).to(topicName);
bind(Publisher.class).annotatedWith(Names.named(publisherName)).to(PublisherImpl.class);
}
}
但这让我无处可去,因为您无法在模块配置方法中获得注入器:
Injector injector = Guice.createInjector(this); // This will throw IllegalStateException : Re-entry is not allowed
injector.createChildInjector(
new PublisherModule("publisherOne", "topicOne"),
new PublisherModule("publisherTwo", "topicTwo"));
唯一简单且有效的解决方案是我将 PublisherImpl 更改为抽象,添加他抽象的“getTopic()”方法并添加另外两个具有主题覆盖的实现。
但这个解决方案是蹩脚的。为代码重用添加额外的继承并不是最佳实践。我也相信 Guice 肯定必须支持这样的功能。
欢迎任何建议。韩国,NEJC