Najlepszym rozwiązaniem dla nas było użycie Assisted Inject.
W zależności od przypadku zdefiniowaliśmy fabryki aktywności w samym działaniu, w pakiecie (do budowania wszystkich działań w tym pakiecie) lub w 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));
BTW, do wstrzykiwań metoda do pracy, trzeba jeszcze stworzyć swoje działania przez gin, więc chcesz mieć takie same problemy jak z wtryskiem konstruktora. Nie ma magii, GIN nie magicznie wstrzykuje klas, o których nie wie i nawet nie wie, kiedy zostały utworzone. Można wywołać metodę iniekcji wyraźnie dodając metody do Ginjector, ale nie polecam go (kod będzie zależeć od Ginjector, która jest coś należy unikać, jeśli to możliwe):
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);
...
Ostatnim słowo: Nie przekazałbym obiektu miejsca bezpośrednio do działania. Postaraj się rozdzielić miejsca i czynności, które pozwolą ci poruszać różnymi sprawami (np. Zbuduj wersję mobilną lub tabletową, w której przełączasz się między widokiem głównym i szczegółowym, zamiast wyświetlać je obok siebie), zmieniając układ "powłoki" i mappers aktywności. Aby naprawdę je rozdzielić, musisz zbudować coś w rodzaju navigator, co spowoduje streszczenie twoich połączeń placeController.goTo()
, dzięki czemu twoje zajęcia nigdy nie będą zajmować miejsc.
Witaj Thomas, Dokładnie to robimy w naszej aplikacji (przy użyciu fabryki) i działa dobrze. Jak jednak zasugerować integrację z Gyn's AsyncProvider w celu podziału kodu? (używamy ActivityAsyncProxy http://ars-codia.raphaelbauer.com/2011/04/gwt-gin-and-simple-split-points.html) –