私が持っていると言うことができます:
public interface Shape {}
public class Rectangle implements Shape {
}
public class Circle implements Shape {
}
ApplicationModuleがあり、これはRecとCircleの両方のインスタンスを提供する必要があります。
@Module
public class ApplicationModule {
private Shape rec;
private Shape circle;
public ApplicationModule() {
rec = new Rectangle();
circle= new Circle ();
}
@Provides
public Shape provideRectangle() {
return rec ;
}
@Provides
public Shape provideCircle() {
return circle;
}
}
およびApplicationComponent:
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
Shape provideRectangle();
}
そのままのコードでは-コンパイルされません。言っているエラー
エラー:(33、20)エラー:図形が複数回バインドされています。
コンポーネントがShape
インスタンスを見つけようとしていて、そのうちの2つを見つけているので、どちらを返すかわからないので、これができないことは理にかなっています。
私の質問は-この問題をどのように処理できますか?
私は最近、この投稿でこのような質問への回答を投稿します:
ダガー2:@Namedで同じオブジェクトの複数のインスタンスを取得中にエラーが発生しました
次のようにモジュールで@Named("someName")
を使用する必要があります。
@Module
public class ApplicationModule {
private Shape rec;
private Shape circle;
public ApplicationModule() {
rec = new Rectangle();
circle= new Circle ();
}
@Provides
@Named("rect")
public Shape provideRectangle() {
return rec ;
}
@Provides
@Named("circle")
public Shape provideCircle() {
return circle;
}
}
その後、あなたがそれらを注入する必要があるところはどこでも書くだけ
@Inject
@Named("rect")
Shape objRect;
その面白いが、Kotlinで別の方法で注入する必要があります。
@field:[Inject Named("rect")]
lateinit var objRect: Shape
@Qualifier
アノテーションは、同じタイプの異なるインスタンスまたはインジェクションリクエストを区別する正しい方法です。メインのユーザーズガイドページには セクション全体 があります。
@Qualifier @Retention(RUNTIME)
public interface Parallelogram {} /* name is up to you */
// In your Module:
@Provides @Parallelogram
public Shape provideRectangle() {
return rec ;
}
// In your other injected types:
@Inject @Parallelogram Shape parallelogramShape;
// or
@Inject @Parallelogram Provider<Shape> parallelogramShapeProvider;
// In your Component:
@Parallelogram Shape provideRectangle();
余談:injected型ではnew
を使用すべきではないというセクター11に同意しますが、new
if必要です。修飾子の注釈を追加することは別として、あなたのモジュールは私にぴったりだと思います。
[〜#〜] edit [〜#〜]カスタム修飾子アノテーションと比較した@Namedの使用に関して:
@Qualifier
アノテーションで、上記で作成したものとよく似ています。単純な場合、それはうまく機能しますが、バインディングは単なる文字列であるため、有効なキーの検出またはキーの自動補完においてIDEからあまり助けを得ることはありません。@Named
およびカスタム修飾子は、上記の@Parallelogram
で行ったように、コンポーネントメソッドでアノテーションを指定することにより、まったく同じ方法でアノテーションからアクセスできます。new
のコンストラクター内でModule
演算子を使用することはお勧めできません。これにより、Daggerがオブジェクトを初めて必要とするときではなく、オブジェクトグラフの初期化時(つまり、new ApplicationModule()
を呼び出したとき)に、提供された各オブジェクトのインスタンスが作成されます。この場合(オブジェクトが2つだけの場合)、それは無視できますが、大規模なプロジェクトでは、アプリケーションの起動時にボトルネックを引き起こす可能性があります。代わりに、@ sector11による提案に従い、_@Provides
_アノテーション付きメソッドでオブジェクトをインスタンス化します。
同じタイプの2つのオブジェクトを提供する場合、@ Jeffと@Amirの両方が正しいです。提供されている@Named()
修飾子を使用するか、次のように独自の修飾子を作成できます。
_@Qualifier @Retention(RetentionPolicy.RUNTIME)
public @interface RectangleShape {}
@Qualifier @Retention(RetentionPolicy.RUNTIME)
public @interface CircleShape {}
_
ApplicationModule
は次のようになります。
_@Module
public class ApplicationModule {
@Provides @RectangleShape // @Named("rectangle")
public Shape provideRectangle() {
return new Rectangle();
}
@Provides @CircleShape // @Named("circle")
public Shape provideCircle() {
return new Circle();
}
}
_
これにより、これらのオブジェクトを次のようにクラスに注入できます。
_@Inject @RectangleShape /* @Named("rectangle") */ public Shape mRectangle;
@Inject @CircleShape /* @Named("circle") */ public Shape mCircle;
_
_@Inject
_アノテーションなしでShape
クラスのインスタンスを提供する必要がある場合は、Component
クラスで提供できます。
_@Component(modules = { ApplicationModule.class })
public interface ApplicationComponent {
void inject(MyApplication application);
@RectangleShape // @Named("rectangle")
Shape getRectangle();
@CircleShape // @Named("circle")
Shape getCircle();
}
_
これらのメソッドは、_@Provides
_アノテーション付きメソッドによって提供される各クラスの同じインスタンスを提供します。
に加えて @Named
およびカスタム修飾子(他の応答に表示)、enum
パラメーターでカスタム修飾子を使用することもできます。
// Definition
@Qualifier
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface ShapeType {
ShapeTypeEnum value(); /* default ShapeTypeEnum.RECTANGLE; */
}
public enum ShapeTypeEnum {
RECTANGLE, CIRCLE
}
// Usage
@Provides @ShapeType(ShapeTypeEnum.RECTANGLE)
public Shape provideRectangle() {
return new Rectangle();
}
@Inject @ShapeType(ShapeTypeEnum.RECTANGLE) Shape rectangle;
これは、@Named
(エラーが発生しやすく、オートコンプリートできないStringキーが必要です)およびカスタム修飾子(実装ごとにファイルが必要です)。