Search code examples
androiddependency-injectionandroid-serviceinversion-of-controldagger-2

Using Dagger 2 to inject into service


I have an app which is basically a service that runs all the time and alarms the user when something happens.

When the service creates the alarm, it needs to give it his context so that the alarm can do callbacks to the service when something happens.

For example:

public MyService extends Service{
    private SomeAlarm alarm;

    @Override
    public void onCreate() {
        super.onCreate();
        alarm = new SomeAlarm(MyService.this);
    }
}

How can I inject the SomeAlarm class into the service, and give the SomeAlarm the service context as a variable?


Solution

  • I wrote the code from the top of my head, so there could be a typo or two.

    You do it just the same as when injecting stuff into activities.

    1. Declare a component,
    2. add the inject method to that component,
    3. add a module providing your service
    4. create that components builder
    5. add your module to the builder
    6. inject your service with the component

    Your module and component would look something like this (maybe add some scope)

    @Module
    class ServiceModule {
    
        MyService mService;
    
        ServiceModule(MyService service) {
            mService = service;
        }
    
        @Provides
        MyService provideMyService() {
            return mService;
        }
    }
    
    @Component(modules=ServiceModule.class)
    interface MyServiceComponent {
        void inject(MyService service);
    }
    

    Then in onCreate just create your component and inject your alarm.

    @Inject
    private SomeAlarm alarm;
    
    public void onCreate() {
        DaggerMyServiceComponent.builder()
                .serviceModule(new ServiceModule(this))
                .build()
                .inject(this);
    
        alarm.doStuff();
    }
    

    This is assuming that your alarm can be constructor injected by having an @Inject annotated constructor like this:

    class SomeAlarm {
        @Inject
        SomeAlarm(MyService service) {
            /*constructor stuff*/
        }
    }
    

    Else you would just also add the alarm creation to your module.