Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement Dagger for worker classes?

Since the Worker class is created by the framework (WorkerManager), how can we use @Inject fields into the Worker?

like image 682
Mehdi Jahed Manesh Avatar asked May 22 '18 07:05

Mehdi Jahed Manesh


People also ask

How does a Dagger work internally?

Dagger generates code similar to what you would have written manually. Internally, Dagger creates a graph of objects that it can reference to find the way to provide an instance of a class. For every class in the graph, Dagger generates a factory-type class that it uses internally to get instances of that type.

Is Dagger deprecated?

It's officially deprecated and you can pretty much ignore it. Google's framework, which became dominant in Android ecosystem, was originally called Dagger 2. Sometimes we still refer to it as such, but, in most cases, we simply call it Dagger today.

Is Dagger better than Guice?

Guice is base on reflection, while Dagger is generating extra code during compile-time; reflection is much slower than the pre-generated code. Dagger is often used in Android development(reflection is even slower in Android) Dagger has simpler APIs, and the stacktrace is easier to understand.


2 Answers

You have to provide class using @Provides annotation in the module to inject.

First create a component containing a module which will provide the class.

@Component(modules = {Module.class})
public interface Component1{

    void inject(SyncWorker syncWorker);
}

Module Class

@Module
public class Module{

    @Provides
    public ISettingRepository getSettingRepo(){
        return new ISettingRepository();
    }

}

Now write in your code, a constructor that is used to inject the component into your worker class.

public class SyncWorker extends  Worker {

    @Inject
    ISettingRepository settingRepository;

    public SyncWorker(){
        DaggerComponent1.builder().build().inject();
    }

    @NonNull
    @Override
    public Result doWork() {

        sync();
        return Result.SUCCESS;
    }

    private void sync() {

    }
}
like image 166
Anisuzzaman Babla Avatar answered Sep 24 '22 15:09

Anisuzzaman Babla


I am using these series of post for implementing dagger in my app and ProfileManager is the class I wnat to inject in my Worker class.

UploadWorker

public class UploadWorker extends Worker {

    @Inject
    ProfileManager profileManager;

    @Inject
    @SuppressWarnings("WeakerAccess")
    public UploadWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
    super(context, workerParams);
     Provider.getAppComponent().inject(this);
    }

    @NonNull
    @Override
    public Result doWork() {
     profileManager.someMethod();
    }

}

In Application class I am setting Appcomponent in my Provider class

   @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        AppComponent appComponent = DaggerAppComponent.builder().application(this).build();
        appComponent.inject(this);
        Provider.setAppComponent(appComponent);
        return appComponent;
    }

Provider

public class Provider {

    private static AppComponent appComponent;

    public static AppComponent getAppComponent() {
        return appComponent;
    }

    public static void setAppComponent(AppComponent component) {
        appComponent = component;
    }

}

Appcomponent

@Singleton
@Component(modules = {
        AndroidSupportInjectionModule.class,
        ActivityBuilderModule.class,
        ApiModule.class,
        AppModule.class,
        ViewModelModule.class
})
public interface AppComponent extends AndroidInjector<DaggerApplication> {

    @Override
    void inject(DaggerApplication instance);

    void inject(MyApplication app);

    void inject(UploadWorker uploadWorker);

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(Application application);

        AppComponent build();
    }

}
like image 33
Levon Petrosyan Avatar answered Sep 26 '22 15:09

Levon Petrosyan