Injecting login session using Dagger

1.4k views Asked by At

I'm adapting my project to utilize DI - Dagger in particular. I have no problems injecting classes, but how do you 'inject' a runtime generated variable?

Say, I want to store user's login session object that contains data such as api-token, loggedUsername and whatnot inside. This object is generated at runtime when the user has successfully logged in, in another class responsible for doing so.

As an illustration, what I want is to simply do something like this:

public class FooPresenter {
    ...

    Session mSession;

    @Inject FooPresenter(Session session, ...) {
        mSession = session;
        ...
    }

    ...
}

Thanks in advance!

2

There are 2 answers

0
Hadi Satrio On BEST ANSWER

I ended up declaring a method to obtain my session, which I kept as a String in SharedPreferences after a successful login, in a Dagger module class.

That way, I could just inject the session anywhere it's needed.

Here's my SessionDomainModule:

@Module(
        library = true,
        complete = false)
public class SessionDomainModule {

    // TODO: Rethink this implementation.
    @Provides
    public Session provideSession(Application application) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(application);
        String sessionJString = preferences.getString(AppConfig.PREF_KEY_CURRENT_SESSION, "");

        Session session;
        if(!"".equals(sessionJString)) {
            return new Gson().fromJson(sessionJString, Session.class);
        }

        return null;
    }
    ...
}

By doing that, I could achieve what I wanted and codes in the like of those on my question could finally work.

1
nhaarman On

You can have a SessionModule which keeps a reference to your current Session:

@Module
class SessionModule {

  @Nullable
  private Session mSession;

  @Provides Session provideSession() {
    return mSession;
  }

  void setSession(Session session) {
    mSession = session;
  }
}

You will need a reference to this SessionModule however to update the session object.


Another way is to create a (singleton) SessionProvider, which does nothing more than holding the Session:

@Singleton
class SessionProvider {

  Session session;

  @Inject
  SessionProvider() {
  }   
}

Then, instead of injecting the Session instance, you would inject the SessionProvider, from which you can retrieve / update the Session.