2

I'm just not getting this:

I use Gin in my java GWT app to do DI. The login screen is integrated into the full application window. After the user has logged in I want to inject the user object into other classes like GUI Presenters which I create, so I have some sort of runtime dependency I believe. How do i do that?

One solution I can think of is sth like:

class Presenter {
  @Inject
  Presenter(LoggedInUserFactory userFactory) {
     User user = userFactory.getLoggedInUser();
  }
}

class LoggedInUserFactoryImpl {
  public static User user;
  User getLoggedInUser() {
    return user;
  }
}

So, when the user is successfully logged in and I have the object i set the static property in LoggedInUserFactory, but this will only work if the Presenter is created after the user has logged in which is not the case.

Or should I use a global static registry? I just don't like the idea of having static dependencies in my classes.

Any input is greatly appreciated.

Fabian
  • 2,428
  • 2
  • 21
  • 19

2 Answers2

2

Instead of bending DI over backwards to supply the User, use an EventBus to fire an event when the user logs in.

If you absolutely must use DI for this and the presenters that require the User aren't used until properly initialized with a non-null User you can defer your call to GWT.create(MyGinjector.class) until after the User is logged in. You would then have two such calls in your application: one for the login code path and a second for the rest of the application.

Jason Terk
  • 6,005
  • 1
  • 27
  • 31
  • the question http://stackoverflow.com/questions/3141969/gwt-gin-adding-user-class-to-all-presenters is related to this, I found it later. I think i'm going to redesign my app to pass the user around via the EventBus since it doesn't seem to be a good fit for DI. I can't use the second path idea mentioned above because my presenters already get initialized. Although it might be an option to redesign my app to defer the loading of the other presenters. – Fabian Jan 07 '11 at 20:41
2

You could use the Provider interface.

class Presenter {
  @Inject
  Presenter(Provider<User> userProvider) {
     User user = userProvider.get();
  }
}

class UserProvider implements Provider<User> {
  public User user;
  User get() {
    return user;
  }
}

Then your module would have a provider binding like this:

bind(User.class).toProvider(UserProvider.class);

EDIT: To set the user variable, client code could obtain the instance of the UserProvider class via a binding like this:

bind(UserProvider.class).in(Singleton.class);

...which would allow the client code to do this:

injector.getInstance(UserProvider.class).user = new User(...)
David
  • 5,184
  • 3
  • 41
  • 67
  • Not to be funny, but how exactly would the provider get the user? A null user isn't exactly what the question had in mind. – gpampara Jan 11 '11 at 06:57
  • Yes, thanks for that gpampara. I've now added a bit to my solution to cover that. – David Jan 12 '11 at 00:47