How to inject a “runtime” dependency like a logged in user which is not available at application boot time?

StackOverflow https://stackoverflow.com/questions/4629777

Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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(...)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top