关于Guice的问题。我还在学习它,但我能理解基础知识。
这个问题已经在网上问了好几次,但从来没有得到具体答案(我找不到)。
假设我的情况与图片类似(网上有类似的例子)。
public class Dog {}
public class Walk implements Walkable {
private final Dog dog;
private final boolean leash;
@Inject
public Walk(Dog dog, @Assisted boolean leash) {
this.dog = dog;
this.leash = leash;
}
public void go() {
}
}
public interface Walkable {
void go();
}
public interface WalkFactory {
Walk create(boolean leash);
}
public class AssistedMain {
public static void main(String[] args) {
Injector i = Guice.createInjector(new AbstractModule() {
protected void configure() {
install(new FactoryModuleBuilder().
implement(Walkable.class, Walk.class).
build(WalkFactory.class));
}
});
Walk walk = i.getInstance(WalkFactory.class).create(true);
}
}
这一切都很棒。但问题是 - 我可以以某种方式将该对象实例重新注入“容器”(注入器),以便在依赖此依赖关系的类上使用。
因此,我们添加interface Person
,class PersonImpl
。
新的类源是:
public interface Person {
void walkDog();
}
public class PersonImpl implements Person {
private Walkable walkable;
@Inject
public PersonImpl(Walkable walkable) {
this.walkable = walkable;
}
public void setWalkable(Walkable walkable) {
this.walkable = walkable;
}
public void walkDog() {
walkable.go();
}
}
所以,问题是 - 我能以某种方式将这个特定实例注入添加的对象中。这是一个简单的例子,但我们可以假设这个类下面有10个级别。
我找到的解决方案不是很灵活。类似的东西:
Injector i = Guice.createInjector(new SimpleModule(false, dog));
然后绑定到具体实例。这不是很有活力。基本上,每次我需要不同的运行时/动态参数时,我都必须重新创建注入器。
Provider<T>
很好,FactoryModuleBuilder
有帮助,但我怎样才能将对象注入?
此问题是否有更多动态解决方案?
感谢。
答案 0 :(得分:4)
最初源于“服务定位器”模式,它可以管理的不仅仅是服务的想法,至少可以说是乐观的。
我们可以将应用程序拆分为服务和数据类,或者您可以说我们有应用程序和基础结构代码 - “依赖注入”,这是一本很棒的书。
因此,基本上,依赖注入和依赖注入框架一般都很棒。 用于解决基础架构或“服务”代码。
注入Container / Injector的任何动态(运行时)参数基本上都是,迫使你结束对象图。
例如,我们有以下设计:
EmailMessage是一个运行时参数。它可以“注入”Container / Injector之外的电子邮件服务,但它会结束对象图。 如果我们想要请求EmailDispatcher,在我们将EmailMessage注入EmailService后(我重复一次,在注射器外部完成),我们就无法再从注射器中获取EmailDispatcher。
然后,您可以重新设计模型,使其“适合”动态参数的Container / Injector概念。
但是,再一次,你强迫设计,突然, EmailDispatcher有太多的责任。它可以在这样的环境中使用,你没有很多基础设施类。
如果您在第三个示例图片中有类似的设计,则无法使用Injector / Container来获取NextService3实例(也不会低于EmailDispatcher的级别)。
问题是 - 如果你有任何动态(运行时)参数,你只能对需要动态参数的类上面的类使用依赖注入,你可以忘记下面的类。
呼。
正确?
答案 1 :(得分:1)
问题的一部分取决于你如何解决'假'是你要为皮带字段设置的东西。这是来自配置数据还是什么?
提供商方法可能会有所帮助......
class FooModule extends AbstractModule {
...
@Provides
Walkable getWalkable(Dog dog) {
boolean leash = getBooleanFromSomewhere();
return new Walk(dog, leash);
}
}
如果你能澄清布尔来自何处,它将帮助我理解适用的方法类型。
答案 2 :(得分:1)
您可以使用custom scopes,就像使用guice servlet时一样。这样您就可以创建实例,然后在注入器中播种它。