Guice Assisted Inject具有多种接口实现

时间:2014-06-04 14:22:25

标签: java dependency-injection guice

我有一个接口A,有多个实现说B,C和D. 我正在使用guice辅助注入来创建这些类。类B和C在构造函数中使用相同的assister参数(比如b,c),而D有一个不同的参数(比如d)。 我实现这个的方式是有一个工厂AFactory有2个方法: create(int b,int c)和createD(int d) 在我的模块中,我创建了一个PrivateModule来将具体类绑定到工厂。

代码如下所示:

public static PrivateModule getAFactoryModule(final String factoryBindingKey,final Class<? extends A> targetClassToCreate) {
    return new PrivateModule() {

        @Override
        public void configure() {
            install(new FactoryModuleBuilder().implement(
                    A.class, targetClassToCreate).build(
                    AFactory.class));

            bind(AFactory.class).annotatedWith(Names.named(factoryBindingKey)).to(
                    Key.get(AFactory.class));
            expose(Key.get(AFactory.class, Names.named(factoryBindingKey)));
        }
    };
}

我这样称为PrivateModule:

install(getAFactoryModule("B", B.class));
install(getAFactoryModule("C", C.class));
install(getAFactoryModule("D", D.class));

但是,这给出了一个错误说:

com.guice.test.B has @AssistedInject constructors but none of them match the parameters in method com.guice.test.AFactory.createD(). Unable to create assisted inject

com.guice.test.C has @AssistedInject constructors but none of them match the parameters in method com.guice.test.AFactory.createD(). Unable to create assisted inject

com.guice.test.D has @AssistedInject constructors but none of them match the parameters in method com.guice.test.AFactory.create(). Unable to create assisted inject

似乎Guice正在尝试使用与预期不同的创建方法。知道如何解决这个问题吗?任何指针都将不胜感激!

谢谢!

1 个答案:

答案 0 :(得分:3)

听起来你正在做一些不安全的事情 - 让你的一些工厂方法无法解决 - 而Guice很困惑。基本上,FactoryModuleBuilder生成以下代码:

@Named("B") public class GeneratedBClass implements AFactory {
  A create(int b, int c) { return new B(...); }
  A create(int d) { /* no implementation! */ }
}
@Named("C") public class GeneratedBClass implements AFactory {
  A create(int b, int c) { return new C(...); }
  A create(int d) { /* no implementation! */ }
}
@Named("D") public class GeneratedBClass implements AFactory {
  A create(int b, int c) { /* no implementation! */ }
  A create(int d) { return new D(...); }
}

这三个缺失的实现是Guice抱怨的原因:Guice无法为那些人找到一个好的实现,并且认为你希望他们连接起来。但是,除了Guice之外,你设计了一个非常危险的API:根据你的配置,你的一种方法会起作用,一种方法无法工作 - 这比DI的设计更危险。

我会将你的配置切换到仅切换&#34; B&#34;和&#34; C&#34;,并且让这两个人暴露了&#34; D&#34;:

public interface AFactory {
  @Named("BorC") A create(int B, int C);
  @Named("D") A create(int D);
}

install(new FactoryModuleBuilder()
    .implement(A.class, Names.named("BorC"), targetClassToCreate)
    .implement(D.class, Names.named("D"), D.class)
    .build(AFactory.class));

...或者,因为你应该在编译时知道你是否要调用双参数或单参数构造函数,只需将D切换到它自己的工厂:

public interface DFactory {
  D create(int D);
}

// If DFactory creates an A, you need implement(). Otherwise, this works.
install(new FactoryModuleBuilder().build(DFactory.class));