2015-03-03 72 views
2

我试图学习Guice,但下面的场景似乎很难。比方说,我有类A,B和C.我应该能够做到以下几点(注意,这个例子稍微简化实际情况):Guice和“范围”单身人士

  1. A是全球单
  2. 一个上有依赖ProviderB(即工厂)
  3. B对A和ProviderC(即工厂)依赖性
  4. C具有的依赖关系和B

当B创建C,C的依赖性B必须是相同的实例即从C的角度来看,B是单身人士。

我曾尝试创建子注入:

private static class MainModule extends AbstractModule{ 

    @Override 
    protected void configure() { 
     bind(A.class).in(Singleton.class); 
    } 

    @Provides 
    B createB(Injector injector){ 
     return injector.createChildInjector(new SubModule()).getInstance(B.class); 
    } 
} 

private static class SubModule extends AbstractModule{ 

    @Override 
    protected void configure() { 
     bind(B.class).in(Singleton.class); 
     bind(C.class); 
    } 
} 

public static void main(String[] args) { 
    Injector injector = Guice.createInjector(new MainModule()); 

    A a = injector.getInstance(A.class); 

    B b1 = a.getB(); 
    B b2 = a.getB(); 

    // all following C's are different instances 
    C b1c1 = b1.getC(); //this has b1 and a 
    C b1c2 = b1.getC(); //this has b1 and a 

    C b2c1 = b2.getC(); //this has b2 and a 
    C b2c2 = b2.getC(); //this has b2 and a 

}

但随后吉斯给出了B已经绑定错误(中MainModule提供的方法)。因此,我需要重写MainModule的B绑定,但这似乎是不可能的,使用子注入器。

该问题可以通过使用多个喷射器来解决,例如,为createB方法创建一个新的方法并注入A作为参数,但似乎使用多个注入器并不是最佳实践。

编辑:添加注释到C实例阐明他们应该有其B的实例

+1

是否有一个原因,MainModule和SubModule不能同时安装到初始注射器,或者你可以'用'@ Singleton'注释'@Provides createB(...)'? – 2015-03-03 19:46:36

+0

嗯,也许我有点不清楚,是否更加清楚,如果我说每个B的依赖关系,B被认为是单身,但在其他地方可以有多个B,即每次A.getB被调用时,它返回一个新实例。如果我用@Singleton对createB进行注释,那么我猜测B会被认为是单身人士。 – 2015-03-04 08:32:31

+0

我还可以注意到目前为止,父注入器只有单例绑定(在这里,在实际应用中更多),所以我可以使用父注入器创建SubModule,注入每个单例,再将它们绑定为单例并创建全新的顶层在使用B之前先要注入高级别的喷油器,但是我想避免再次写入它们。 – 2015-03-04 08:46:19

回答

1

我会后这是一个答案,它更像解决方法不是完整的解决方案,但可能是我的应用程序不够好反正:

private static class MainModule extends AbstractModule{ 

    @Override 
    protected void configure() { 
     bind(A.class).in(Singleton.class); 
     bind(SubModule.class).in(Singleton.class); 
    } 

    @Provides 
    B createB(Injector injector){ 
     SubModule m = injector.getInstance(SubModule.class); 
     return Guice.createInjector(m).getInstance(B.class); 
    } 
} 

private static class SubModule extends AbstractModule{ 

    private final A a; 

    @Inject 
    public SubModule(A a) { 
     this.a = a; 
    } 

    @Override 
    protected void configure() { 
     bind(A.class).toInstance(a); 
     bind(B.class).in(Singleton.class); 
     bind(C.class); 
    } 
} 

首先我因子评分,大部分的绑定将在MainModule,但我想他们可以移动到子模块无论如何,如果他们在B(和路线别人像我一样用的情况下只用一个)。这大部分与链接问题的答案相似: Dependency injection: Scoping by region (Guice, Spring, Whatever)但我创建了新的顶级进样器,因为它似乎无法在两个模块中都绑定B,或者我可能会错过这里的某些内容。

(First time doing这不知道是否这是正确的方式做一个解决方案作为自己的答案)