dom*_*nus 44 android dagger dagger-2
我开始使用Dagger 2并遇到一个奇怪的问题,看起来像是一个bug.
我有3个模块,它们组成一个子组件,后者又扩展/加载更高级别的组件.
子组件非常简单:只需组合模块和单个注入点:
@Singleton
@Subcomponent(
modules = {
NavigationDrawerModule.class,
NavigationListModule.class,
SwitcherModule.class
}
)
public interface NavigationDrawerComponent {
NavigationDrawerFragment inject(NavigationDrawerFragment object);
}
Run Code Online (Sandbox Code Playgroud)
第一个模块看起来像这样 - 它提供了一般的片段级依赖关系:
@Module
public class NavigationDrawerModule {
private final Activity activity;
private final View rootView;
private final LoaderManager loaderManager;
public NavigationDrawerModule(Activity activity, View rootView, LoaderManager loaderManager) {
this.activity = activity;
this.rootView = rootView;
this.loaderManager = loaderManager;
}
@Provides @Singleton EventBus provideLocalBus() {
return EventBus.builder().build();
}
@Provides @Singleton View provideViewRoot() {
return rootView;
}
@Provides @Singleton LoaderManager provideLoaderManager() {
return loaderManager;
}
@Provides @Singleton Context provideContext() {
return activity;
}
}
Run Code Online (Sandbox Code Playgroud)
第二个模块看起来像这样 - 它为屏幕上的UI子集提供演示者/控制器及其依赖关系:
@Module
public class SwitcherModule {
@Provides SwitchController provideSwitcherController(SwitchControllerImpl impl) {
return impl;
}
@Provides SwitcherView provideSwitcherView(SwitcherViewImpl impl) {
return impl;
}
}
Run Code Online (Sandbox Code Playgroud)
第三个模块 - 用于UI子集的另一个演示者/控制器:
@Module
public class NavigationListModule {
@Provides @Singleton NavigationListController provideNavigationListController(NavigationListControllerImpl impl) {
return impl;
}
@Provides @Singleton NavigationListView provideNavigationListView(NavigationListViewImpl impl) {
return impl;
}
}
Run Code Online (Sandbox Code Playgroud)
正在注入的片段的相关部分:
@Inject SwitchController identitySwitchController;
@Inject SwitcherView identitySwitcherView;
@Inject NavigationListController navigationListController;
@Inject NavigationListView navigationListView;
Run Code Online (Sandbox Code Playgroud)
NavigationListControllerImpl
实现以下构造函数:
@Inject
public NavigationListControllerImpl(Context ctx, EventBus bus) {
this.ctx = ctx;
this.bus = bus;
}
Run Code Online (Sandbox Code Playgroud)
我从Dagger 2编译器得到的错误如下:
error: ...sidenavigation.navigationlist.NavigationListControllerImpl cannot be provided without an @Inject constructor or from an @Provides-annotated method.
...sidenavigation.NavigationDrawerFragment.navigationListController
[injected field of type: ...sidenavigation.navigationlist.NavigationListController navigationListController]
...sidenavigation.navigationlist.NavigationListModule.provideNavigationListController(...sidenavigation.navigationlist.NavigationListControllerImpl impl)
[parameter: ...sidenavigation.navigationlist.NavigationListControllerImpl impl]
Run Code Online (Sandbox Code Playgroud)
错误抱怨缺少@Inject-annotated构造函数,但它存在!如果我@Provides
用explicit(with new
)替换隐式的NavigationListControllerImpl实例创建(通过-method参数传递),dagger开始抱怨相同的错误,但现在对于同一模块中的第二个条目的presenter对象,依此类推.
所有这些情况看起来都很奇怪,我想听听更有经验的Dagger 2用户(和开发人员?)的一些意见.
先感谢您!
s-h*_*ter 50
我得到了同样的错误,因为我忘了将父组件中的模块提供的对象暴露给依赖它的其他组件.
父组件示例:
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
AppPref exposeAppPref(); /* my issue was caused by forgot this line,
the method name doesn't matter, what matters is the object type AppPref provided in the AppModule
that you want it to be available in the component that declares this component as one of its dependencies*/
}
Run Code Online (Sandbox Code Playgroud)
将上述组件作为依赖项的示例组件
@UserScope
@Component (dependencies = {AppComponent.class})
public interface ActivityComponent {
void inject(MainActivity activity);
}
Run Code Online (Sandbox Code Playgroud)
更新:
的AppModule:
...
@Provides
@Singleton
AppPref provideAppPref() {
return appPref;
}
...
Run Code Online (Sandbox Code Playgroud)
luk*_*kas 18
GlobalComponent和子组件NavigationDrawerComponent必须具有不同的范围.将@Singleton用于GlobalComponent,将另一个范围用于子组件.
否则,如果将相同的范围应用于GlobalComponent和子组件,则还必须在全局组件中声明子组件的模块:
@Component(
// modules from subcomponent must be declared here also
modules = {NavigationListModule.class,
SwitcherModule.class,
NavigationDrawerModule.class,
...}
)
@Singleton
public interface GlobalComponent {
NavigationDrawerComponent plus(NavigationDrawerModule module);
}
Run Code Online (Sandbox Code Playgroud)
对于您的用例,您还可以使用组件依赖项.例如:
@Component(
dependencies = GlobalComponent.class,
modules = {NavigationListModule.class,
SwitcherModule.class,
NavigationDrawerModule.class}
)
@YourOtherDaggerScope // @Singleton scope won't work here, it must be a different scope
public interface NavigationDrawerComponent extends GlobalComponent { // extend the parent component if you wish to get access to parent dependencies
NavigationDrawerFragment inject(NavigationDrawerFragment object);
}
Run Code Online (Sandbox Code Playgroud)
dom*_*nus 16
好像我已经弄清楚我的Dagger 2设置有什么问题了.在组件和子组件中都不可能使用相同的范围.它需要定义子一个新的范围.在我的情况下,我最终为我的子组件创建了@Screen范围.
我要说这是Dagger 2中的一个小但非常烦人的缺陷.显然,如果使用父组件作为依赖项扩展子组件,则dagger-compiler会报告关于父组件和子组件中相同范围的良好且可理解的错误.但是,如果父组件和子子组件共享相同的范围,则编译器会报告完全误导性的错误.
谢谢@lukas,在这里给我一个提示/sf/answers/2126816191/导致问题解决.
今天也遇到这个问题了。对我来说,注释处理存在问题(在带有 gradle 2.x 的 Android Studio 2.2 上)。
我使用了我使用的annotationProcessor而不是~~apt~~
annotationProcessor 'com.google.dagger:dagger-compiler:2.6'
现在它正在发挥作用。
归档时间: |
|
查看次数: |
58474 次 |
最近记录: |