I have moduleA setup as an application wide singleton provider, ModuleB as a user related object provider
My user display fragment will use system wide bus to send message to others and use user related object to display.
Problem cannot inject different scrope class into one object. Use component.getX method works fine, but inject is prefered way. Error message: @UserScope may not reference bindings with difference scopes: @Provides @Singleton Bus ModuleA.provideBus()
@Module
public class ModuleA {
@Provides @Singleton Bus provideBus() {...}
}
Module B as user related Info provider
@Module
public class ModuleB{
private final User user;
public ModuleB(User user) {...}
@Provides @UserScope User provideUser() {}
@Provides @UserScope UserManager provideUserManager() {}
}
Components setup like following:
@Component (modules={ModuleA.class})
@Singleton
public interface ComponentA {
Bus getBus();
void inject(ClassA target);
}
@Component(modules={ModuleB.class})
@UserScope
public interface ComponentB {
User getUser();
UserManager getUserManager();
void inject(ClassA target);
}
class UserFragment exrtends Fragment {
@Inject Bus bus;
@Inject UserManager userManager;
public void onCreate() {
getComponentA().inject(this);
getComponentB().inject(this);
}
}
Defining dependencies (object consumers) You use the @Inject annotation to define a dependency. If you annotate a constructor with @Inject , Dagger 2 can also use an instance of this object to fulfill dependencies. This was done to avoid the definition of lots of @Provides methods for these objects.
create custom scopes with Dagger is pretty easy, you just have to follow these steps. Step 1) declare your annotation. Step 2) annotate the dependencies with this annotation in the module.
A Dagger module is a class that is annotated with @Module . There, you can define dependencies with the @Provides annotation. Kotlin Java. // @Module informs Dagger that this class is a Dagger Module.
inject. Inject annotation to identify which constructors and fields it is interested in. Use @Inject to annotate the constructor that Dagger should use to create instances of a class. When a new instance is requested, Dagger will obtain the required parameters values and invoke this constructor.
Try this configuration, it works for me. There is really a lack of good documentation about Dagger2 so I studied a few open-source examples of code that you can find in GitHub etc by keyword like Dagger2.
Application level Component
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
// exported for child-components
Bus eventBus();
}
Application level Module
@Module
public class AppModule {
@Provides @Singleton
Bus provideBus() {
return BusProvider.getInstance();
}
}
Activity level Component
@ActivityScope
@Component(dependencies=AppComponent.class, modules=MainActivityModule.class)
public interface MainActivityComponent {
void inject( MainActivity mainActivity );
}
Activity level Module
@Module
public class MainActivityModule {
private final MainActivity mActivity;
public MainActivityModule( MainActivity activity ) {
mActivity = activity;
}
@Provides
MainActivityTitleController provideTitleController() {
return new MainActivityTitleController( mActivity );
}
}
Android Application class
public class MyApplication extends Application {
private AppComponent mAppComponent;
@Override
public void onCreate() {
super.onCreate();
// Dagger2
mAppComponent = Dagger_AppComponent.builder()
.appModule( new AppModule( this ))
.build();
}
public AppComponent getComponent() {
return mAppComponent;
}
public static AppComponent getComponent( Context context ) {
return ((MyApplication)context.getApplicationContext()).getComponent();
}
}
And finally Activity
public class MainActivity extends ActionBarActivity {
// Injectable fields
@Inject Bus mEventBus;
@Inject MainActivityTitleController mTitleController;
private MainActivityComponent mComponent;
@Override
protected void onCreate( Bundle savedInstanceState ) {
// Dagger2
mComponent = Dagger_MainActivityComponent.builder()
.appComponent( ((MyApplication)getApplication()).getComponent() )
.mainActivityModule( new MainActivityModule( this ) )
.build();
mComponent.inject( this );
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With