2011-12-13 51 views
33

我有这个类:Guice初学者 - 如何绑定具体类?

public class House { 
    private final Door door; 
    private final Window window; 
    private final Roof roof; 

    @Inject 
    public House(Door door, Window window, Roof roof) { 
     this.door = door; 
     this.window = window; 
     this.roof = roof; 
    } 
} 

DoorWindowRoof是具体的类。现在,如果我想要实现这个方案的模块,我会做这样的:

public class HouseModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     bind(Door.class).to(Door.class); 
     bind(Window.class).to(Window.class); 
     bind(Roof.class).to(Roof.class); 
    } 
} 

但我不知道这是否是结合具体的类以正确的方式,或者有更简单的方法。我觉得有一个更简单的方法来解决这个问题。

编辑

只是尝试这样做了,它似乎并没有工作:

1) Binding points to itself. 
    at de.tarent.guice.ex._1.HouseModule.configure(HouseModule.java:10) 

EDIT 2

好像是需要在所有没有约束力:

Injector injector = Guice.createInjector(); 
House house = injector.getInstance(House.class); 

也似乎工作。

回答

22

guice的Just-In-Time binding完全是你想要的。鉴于你DoorWindowRoof具备以下条件(从吉斯documentation引用):

无论是公共,无参数的构造函数,或与@Inject注释的构造

空模块实施将是足够的:

public class HouseModule extends AbstractModule { 
    @Override 
    protected void configure() { 
    } 
} 
+0

空模块在哪里? Guice如何知道与他们联系? – djechlin

+0

@djechlin这取决于你的应用程序的配置。例如,基于[Play](https://www.lightbend.com/play-framework)的应用程序会希望这样的模块文件位于根包中,或者可以通过应用程序中的“play.modules.enabled”进行配置.conf文件 – Siddhartha

40

这是要走的路:

protected void configure() { 
    bind(Door.class); 
    bind(Window.class); 
    bind(Roof.class); 
} 

因为它们是具体的类,如吉斯说,你不能将它们绑定到自己:-)

退房的Binder文档,它注意事项:

bind(ServiceImpl.class); 

本声明基本上就没什么;它“将自己的类绑定到ServiceImpl”,并且不会改变Guice的默认行为。如果您更喜欢Module类作为它提供的服务的显式清单,那么您仍然可以使用它。此外,在极少数情况下,Guice可能无法在注射器创建时验证绑定,除非明确给出。

具有标记为@Inject的构造函数的具体类自动可用于注射。但它有助于开发人员(您)了解模块中配置的内容。

+0

真的很困惑 - “模块中自动可用”意味着您的项目全球所有模块?还是知道包本地模块还是根据模块名称或其他内容匹配? – djechlin

+0

这只是意味着你甚至不必指出如何绑定,因为门,窗和屋顶都是具体的类。它们可用于所有模块。如果你有一个给定接口的不同实现,那么你必须帮助Guice。 – Jalayn

+0

当您不需要将接口绑定到类时,您不需要模块。 – Noya

6

绑定是需要链接接口和实现类(更改为测试环境中的其他实现例如)。但既然你有具体的类,不需要绑定,只是绑定类