Dagger 2 - 提供具有自己依赖性的方法
Dagger 2 - Provides methods to have dependencies of their own
我正在尝试理解和实现 Dagger 2。我已经阅读了很多不同的教程和官方 documentation。我想我大体上理解了它,但我仍然无法理解一些简单的要点(虽然我写了它,但我已经找到了一些解决方案但是..):
It's possible for @Provides methods to have dependencies of their own.
什么时候可以?
我看到有可能得到"component contains a dependency cycle"。
谁能帮助我了解可能和不可能的情况。
谢谢
经过很长一段时间的多次实验,我找到了答案。
我把这个答案作为自己的提示卡,希望它能帮助其他 daggers jedis。
所以我们有了匕首结构
- Android应用程序
- 基础活动
- 导航器
- ApplicationComponent
- 应用模块
- ...
ApplicationComponent.class
@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
void inject(BaseActivity baseActivity);
Navigator navigator();
Context context();
//...
}
ApplicationModule.class
@Module
public class ApplicationModule {
private final AndroidApplication application;
public ApplicationModule(AndroidApplication application) {
this.application = application;
}
@Provides
@Singleton
Navigator provideNavigator() {
return new Navigator();
}
@Provides
@Singleton
Context provideApplicationContext() {
return this.application;
}
}
Navigator.class
@Singleton
public class Navigator implements BaseNavigator {
public Navigator() {}
}
BaseActivity.class
public abstract class BaseActivity extends Activity {
@Inject
Navigator navigator;
//code here
}
此代码将起作用,BaseActivity 将获得由 ApplicationModule 提供的 new Navigator() 导航器。
但是如果你有多个 BaseNavigator class 的实现,你可以获得一些特定的实现,例如 Navigator class 无需手动创建新实例。
*这个构造会给你"component contains a dependency cycle"
@Provides
@Singleton
Navigator provideNavigator(Navigator navigator) {
return navigator;
}
你可以这样做:
ApplicationComponent.class
@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
void inject(BaseActivity baseActivity);
BaseNavigator navigator(); // changed to interface type
Context context();
//...
}
ApplicationModule.class
@Module
public class ApplicationModule {
private final AndroidApplication application;
public ApplicationModule(AndroidApplication application) {
this.application = application;
}
@Provides
@Singleton
BaseNavigator provideNavigator(Navigator navigator) {
return navigator;
} // this will return interface type but with implementation you needed
@Provides
@Singleton
Context provideApplicationContext() {
return this.application;
}
}
Navigator.class
@Singleton
public class Navigator implements BaseNavigator {
@Inject // don't forget to add this annotation to the constructor
public Navigator() {}
}
BaseActivity.class
public abstract class BaseActivity extends Activity {
@Inject
BaseNavigator navigator;// changed to interface type
//code here
}
现在您没有为 Navigator 创建新的 实例 ,Dagger 在其生成的工厂中代替您创建了它。
实际上,您可以使用限定符(@Named("something")
注释)为给定的依赖项获得多个不同类型的实现。
@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
void inject(BaseActivity baseActivity);
@Named("first")
BaseNavigator firstNavigator();
@Named("second")
BaseNavigator secondNavigator();
Context context();
//...
}
@Module
public class ApplicationModule {
private final AndroidApplication application;
public ApplicationModule(AndroidApplication application) {
this.application = application;
}
@Provides
@Singleton
@Named("first")
BaseNavigator provideFirstNavigator() {
return new SomeNavigator();
}
@Provides
@Singleton
@Named("second")
BaseNavigator provideSecondNavigator() {
return new OtherNavigator();
}
@Provides
Context provideApplicationContext() {
return this.application;
}
}
public abstract class BaseActivity extends Activity {
@Inject
@Named("second")
BaseNavigator navigator;
我正在尝试理解和实现 Dagger 2。我已经阅读了很多不同的教程和官方 documentation。我想我大体上理解了它,但我仍然无法理解一些简单的要点(虽然我写了它,但我已经找到了一些解决方案但是..):
It's possible for @Provides methods to have dependencies of their own.
什么时候可以?
我看到有可能得到"component contains a dependency cycle"。
谁能帮助我了解可能和不可能的情况。
谢谢
经过很长一段时间的多次实验,我找到了答案。 我把这个答案作为自己的提示卡,希望它能帮助其他 daggers jedis。
所以我们有了匕首结构
- Android应用程序
- 基础活动
- 导航器
- ApplicationComponent
- 应用模块
- ...
ApplicationComponent.class
@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
void inject(BaseActivity baseActivity);
Navigator navigator();
Context context();
//...
}
ApplicationModule.class
@Module
public class ApplicationModule {
private final AndroidApplication application;
public ApplicationModule(AndroidApplication application) {
this.application = application;
}
@Provides
@Singleton
Navigator provideNavigator() {
return new Navigator();
}
@Provides
@Singleton
Context provideApplicationContext() {
return this.application;
}
}
Navigator.class
@Singleton
public class Navigator implements BaseNavigator {
public Navigator() {}
}
BaseActivity.class
public abstract class BaseActivity extends Activity {
@Inject
Navigator navigator;
//code here
}
此代码将起作用,BaseActivity 将获得由 ApplicationModule 提供的 new Navigator() 导航器。
但是如果你有多个 BaseNavigator class 的实现,你可以获得一些特定的实现,例如 Navigator class 无需手动创建新实例。
*这个构造会给你"component contains a dependency cycle"
@Provides
@Singleton
Navigator provideNavigator(Navigator navigator) {
return navigator;
}
你可以这样做:
ApplicationComponent.class
@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
void inject(BaseActivity baseActivity);
BaseNavigator navigator(); // changed to interface type
Context context();
//...
}
ApplicationModule.class
@Module
public class ApplicationModule {
private final AndroidApplication application;
public ApplicationModule(AndroidApplication application) {
this.application = application;
}
@Provides
@Singleton
BaseNavigator provideNavigator(Navigator navigator) {
return navigator;
} // this will return interface type but with implementation you needed
@Provides
@Singleton
Context provideApplicationContext() {
return this.application;
}
}
Navigator.class
@Singleton
public class Navigator implements BaseNavigator {
@Inject // don't forget to add this annotation to the constructor
public Navigator() {}
}
BaseActivity.class
public abstract class BaseActivity extends Activity {
@Inject
BaseNavigator navigator;// changed to interface type
//code here
}
现在您没有为 Navigator 创建新的 实例 ,Dagger 在其生成的工厂中代替您创建了它。
实际上,您可以使用限定符(@Named("something")
注释)为给定的依赖项获得多个不同类型的实现。
@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
void inject(BaseActivity baseActivity);
@Named("first")
BaseNavigator firstNavigator();
@Named("second")
BaseNavigator secondNavigator();
Context context();
//...
}
@Module
public class ApplicationModule {
private final AndroidApplication application;
public ApplicationModule(AndroidApplication application) {
this.application = application;
}
@Provides
@Singleton
@Named("first")
BaseNavigator provideFirstNavigator() {
return new SomeNavigator();
}
@Provides
@Singleton
@Named("second")
BaseNavigator provideSecondNavigator() {
return new OtherNavigator();
}
@Provides
Context provideApplicationContext() {
return this.application;
}
}
public abstract class BaseActivity extends Activity {
@Inject
@Named("second")
BaseNavigator navigator;