13

これまでのところ、私は google guice 2 をうまく使っていました。guice 3.0 に移行している間、支援された注入ファクトリーに問題がありました。次のコードを想定します

public interface Currency {}
public class SwissFrancs implements Currency {}

public interface Payment<T extends Currency> {}
public class RealPayment implements Payment<SwissFrancs> {
    @Inject
    RealPayment(@Assisted Date date) {}
}

public interface PaymentFactory {
    Payment<Currency> create(Date date);
}

public SwissFrancPaymentModule extends AbstractModule {
    protected void configure() {
        install(new FactoryModuleBuilder()
             .implement(Payment.class, RealPayment.class)
             .build(PaymentFactory.class));
    }
}

インジェクターの作成中に、次の例外が発生します。

com.google.inject.CreationException: Guice creation errors:

1) Payment<Currency> is an interface, not a concrete class.
   Unable to create AssistedInject factory. while locating Payment<Currency>
   at PaymentFactory.create(PaymentFactory.java:1)

guice 2 の支援された注入クリエーターを使用すると、構成が機能します。

bind(PaymentFactory.class).toProvider(
FactoryProvider.newFactory(PaymentFactory.class, RealPayment.class));

これまでに見つけた唯一の回避策は、ファクトリ メソッドの戻り値の型からジェネリック パラメーターを削除することです。

public interface PaymentFactory {
    Payment create(Date date);
}

guice 3 がファクトリ メソッドのジェネリック パラメータを好まない理由や、支援された注入ファクトリについて私が一般的に誤解していることを知っている人はいますか? ありがとう!

4

1 に答える 1

12

上記のコードには2つの問題があります。

まず、をRealPayment実装しますPayment<SwissFrancs>が、をPaymentFactory.create返しますPayment<Currency>Payment<SwissFrancs>を返すメソッドからAを返すことはできませんPayment<Currency>。のreturntypeをに変更するcreatePayment<? extends Currency>RealPaymentが機能します(これは、Paymentを拡張するもののためのものであるためCurrency)。

次に、最初の引数としてimplementを使用するバージョンを使用する必要があります。TypeLiteralそのための方法は、匿名の内部クラスを使用することです。「支払い」を表すために使用できます

new TypeLiteral<Payment<? extends Currency>>() {}

TypeLiteral詳細については、そのコンストラクターのJavadocを参照してください。

于 2011-04-20T21:55:54.010 に答える