我目前正在编写一些框架代码,为我们平台中的服务提供蓝图,以便服务实现者可以专注于特定于服务的逻辑而不是样板集成代码。依赖注入是通过guice完成的。
蓝图有两种类型的逻辑组件;
每个逻辑组件都依赖于集成组件。
集成组件依赖于所有逻辑组件。
由于这是框架代码,因此框架不了解任何具体细节,因此无法静态声明依赖关系并形成依赖关系图。我想避免让服务实现者这样做,因为这意味着他们正在重复自己(只是声明他们有n个业务逻辑模块意味着他们有这种循环依赖)。
我的问题是,如果没有使服务实现者编写样板代码,我可以采取哪些方法
请注意,此处不提供多绑定,因为出于此问题范围之外的各种原因,每个业务逻辑组件必须是PrivateModule。
一个人为的例子来说明
可以通过更改
使此示例正常工作@Provides @Exposed @Named("result")
public String go(Container in) {
return in.format();
}
到
@Provides @Exposed @Named("result")
public String go(@Named("a") Container in, @Named("b") Container in2, @Named("c") Container in3) {
return in.format();
}
即。通过实际创建循环依赖。
import com.google.inject.Exposed;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import java.util.ArrayList;
import java.util.List;
public class GuiceCircularDependencyTest {
public static void main(String[] args) {
Injector in = Guice.createInjector(new Owner());
String result = in.getInstance(Key.get(String.class, Names.named("result")));
System.out.println("Result is: " + result);
}
public static class Owner extends PrivateModule {
@Override
protected void configure() {
bind(Container.class).in(Singleton.class);
install(new Integration());
install(new ModuleA());
install(new ModuleB());
install(new ModuleC());
expose(String.class).annotatedWith(Names.named("result"));
}
}
public static class ModuleA extends PrivateModule {
@Override
protected void configure() {
}
@Provides @Exposed @Named("a")
public Container go(Container in, Wrapper prefix) {
in.add(prefix + "A");
return in;
}
}
public static class ModuleB extends PrivateModule {
@Override
protected void configure() {
}
@Provides @Exposed @Named("b")
public Container go(Container in, Wrapper prefix) {
in.add(prefix + "B");
return in;
}
}
public static class ModuleC extends PrivateModule {
@Override
protected void configure() {
}
@Provides @Exposed @Named("c")
public Container go(Container in, Wrapper prefix) {
in.add(prefix + "C");
return in;
}
}
public static class Integration extends PrivateModule {
@Override
protected void configure() {
bind(Wrapper.class).toInstance(new Wrapper("Module"));
expose(Wrapper.class);
}
@Provides @Exposed @Named("result")
public String go(Container in) {
return in.format();
}
}
public static class Container {
private List<String> strings = new ArrayList<>();
public void add(String string) {
strings.add(string);
}
public String format() {
return strings.toString();
}
}
public static class Wrapper {
private final String prefix;
public Wrapper(String prefix) {
this.prefix = prefix;
}
@Override
public String toString() {
return prefix;
}
}
}
答案 0 :(得分:0)
允许在私有模块之间共享Multibinder
的一种解决方法是将PrivateModule
包装在只安装AbstractModule
的{{1}}实现中并绑定公开了PrivateModule
Multibinder