私たちにとって最も効果的だったのは、Assisted Inject を使用することでした。
ケースに応じて、アクティビティ自体、パッケージ (そのパッケージ内のすべてのアクティビティを構築するため)、または ActivityMapper でアクティビティ ファクトリを定義しました。
public class MyActivity extends AbstractActivity {
private final MyView view;
@Inject
MyActivity(MyView view, @Assisted MyPlace place) {
this.view = view;
...
}
...
}
public class MyActivityMapper implements ActivityMapper {
public interface Factory {
MyActivity my(MyPlace place);
FooActivity foo(FooPlace place);
...
}
// using field injection here, feel free to replace by constructor injection
@Inject
private Factory factory;
@Overrides
public Activity getActivity(Place place) {
if (place instance MyPlace) {
return factory.my((MyPlace) place);
} else if (place instance FooPlace) {
return factory.foo((FooPlace) place);
}
...
}
}
// in the GinModule:
install(new GinFactoryModuleBuilder().build(MyActivityMapper.Factory.class));
ところで、メソッド インジェクションを機能させるには、GIN を使用してアクティビティを作成する必要があるため、コンストラクター インジェクションと同じ問題が発生します。魔法はありません.GINは、インスタンス化されたときに知らない、さらには知らないクラスを魔法のように注入しません。Ginjector にメソッドを追加することで明示的にメソッド インジェクションをトリガーできますが、お勧めしません (コードは Ginjector に依存するため、可能であれば避けるべきものです)。
interface MyGinjector extends Ginjector {
// This will construct a Foo instance and inject its constructors, fields and methods
Foo foo();
// This will inject methods and (non-final) fields of an existing Bar instance
void whatever(Bar bar);
}
...
Bar bar = new Bar("some", "arguments");
myGinjector.whatever(bar);
...
最後に一言: place オブジェクトをアクティビティに直接渡すつもりはありません。「シェル」レイアウトとアクティビティ マッパー。それらを本当に分離するには、何らかのナビゲーターplaceController.goTo()
を作成する必要があります。これにより、呼び出しが抽象化され、アクティビティが場所を処理しないようになります。