0

I have an Activity, which does an initial inject to get some values. It then subscribes (using Otto of course) to changes from an IntentService (which does a simple sync with my back-end server). After this it begins to do some processing, with values from the database, which it did not have initially (i.e. at the time of construction).

What I essentially want to do is ask Dagger, to do a "re-injection" for a module, because of updated information, due to external circumstances.

I currently, inject the parent module class, and then manually call the provides method again, to get hold of the latest information.

Here's how my module looks like

@Module(
    injects = { MyActivity.class}
)
public class SessionModule {

    private Event _currentEvent;

    @Provides
    @Singleton
    SessionModule provideSessionModule() {
        return this;
    }

    @Provides
    @Singleton
    @Named("current")
    public Event provideCurrentEvent() {

        if (_currentEvent == null) {
            _currentEvent = getCurrentEvent_fromStoredPreferencesId();
        }

        if (_currentEvent == null) {
            _currentEvent = getCurrentEvent_fromFirstEventInDatabase();
        }

        return _currentEvent;
    }

    private Event getCurrentEvent_fromStoredPreferencesId() {
        return Event.findEventById(SharedPrefs.getIntPref(KEY_CURRENT_EVENT_ID));
    }

    private Event getCurrentEvent_fromFirstEventInDatabase() {
        List<Event> events = Event.getAll();

        if (events.isEmpty()) {
            return null;
        }

        Event firstEvent = events.get(0);
        PkkSharedPreferencesHelper.setIntPref(KEY_CURRENT_EVENT_ID, firstEvent.getId());
        return firstEvent;
    }

    public void clearAllSessionInformation() {
        _currentEvent = null;
        _currentUser = null;
    }
}

And now in my activity this is what happens:

public class MyActivity
    extends BaseActivity {

    @Inject @Named("current") Event _currentEvent;
    @Inject SessionModule _session;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ...
        MyApp.get(this).inject(this);
        getBus().register(this);
        // ...

        // _currentEvent is null, because SharedPrefs & Db both don't have any info yet.

        startAnIntentService_ForSyncingLatestData();
    }

    // ...

    @Subscribe
    public void onSyncFinished(SyncIntentService.SyncFinishedEvent syncFinishedEvent) {

        assert(_currentEvent == null);  // arr.. _currentEvent is null

        // because the database populated some events only "after" the sync
        // and didn't have anything when Dagger did the initial bootstrap/injection.

        // manually get the event from the @Module
        _currentEvent = _session.provideCurrentEvent();

        assert(_currentEvent != null);
    }
}

This works, but:

  • Is there some method, i can do to "kick-start" a re-inject?
  • Am i fundamentally using Dagger incorrectly or is this kind of usage, fair game?
  • If this is an incorrect strategy, is there a better one for handling this specific case?
KG -
  • 7,130
  • 12
  • 56
  • 72

1 Answers1

3

Kaushik,

You can use constructor injection by talking to the object graph directly and passing in the class you're requesting, in this case, Event.

Although that would be a way to re-inject the object, I don't think this is a good use case for Dagger, you're better off constructing that class in runtime. Unless there's a good reason to use Dagger in this case?

Chris

Chris Arriola
  • 1,636
  • 3
  • 17
  • 23
  • Thanks Chris. that totally makes sense. I think this is an example of me trying to over-use Dagger beyond its true purpose. – KG - Apr 24 '14 at 17:45