我正在尝试使用https://google.github.io/dagger/android创建UserScope我有@Singleton
,@ActivityScope
,@FragmentScope
和@UserScope
。
AppComponent
@Singleton
@Component(
modules = [
AndroidSupportInjectionModule::class,
ActivityBindingModule::class,
AppModule::class,
ApiModule::class
]
)
interface AppComponent {
fun inject(application: Application)
fun createUserComponent(): UserComponent.Builder
@Component.Builder
interface Builder {
@BindsInstance
fun application(app: Application): Builder
fun apiModule(module: ApiModule): Builder
fun build(): AppComponent
}
}
UserComponent:
@UserScope
@Subcomponent(
modules = [UserModule::class]
)
interface UserComponent {
@Subcomponent.Builder
interface Builder {
@BindsInstance
fun user(user: User): Builder
fun build(): UserComponent
}
}
UserModule:
@Module
class UserModule {
@UserScope
@Provides
fun provideUser(user: User): User = user
}
以下是我在成功登录后创建UserComponent
的方式:
private fun createSession(user: User) {
userComponent = appComponent.createUserComponent().user(user).build()
}
我还有UserManager,它引发User
注入构造函数参数的问题
@UserScope
class SomeManager @Inject constructor(
private val apiService: ApiService,
private val user: User
) {}
错误讯息:错误:[dagger.android.AndroidInjector.inject(T)] 如果没有@Inject,则无法提供domain.model.authorize.User 构造函数或来自@ Provide-annotated方法。
di.modules.MainActivityBindingModule_ContributeUserFragment.UserFragmentSubcomponent 使用@ di.scopes.FragmentScope作用域可能不会引用绑定 不同的范围:@ di.scopes.UserScope类 domain.managers.SomeManager
我想创建@UserScope
来管理相关的ApiManagers
生命周期
@Module
class UserFragmentModule {
@Provides
@FragmentScope
fun provideViewModelFactory(someModule: SomeModule) = UserFragmentViewModelFactory(someModule)
}
ContributesAndroidInjector逻辑:
@Module
interface ActivityBindingModule {
@ActivityScope
@ContributesAndroidInjector(modules = [SplashModule::class])
fun contributeSplashActivity(): SplashActivity
@ActivityScope
@ContributesAndroidInjector(modules = [SignInModule::class])
fun contributeAuthorizeActivity(): Activity
@ActivityScope
@ContributesAndroidInjector(modules = [MainModule::class])
fun contributeMainActivity(): MainActivity
}
@Module(includes = [MainActivityBindingModule::class])
class MainModule
@Module
interface MainActivityBindingModule {
@FragmentScope
@ContributesAndroidInjector(modules = [UserFragmentModule::class])
fun contributeUserFragment(): UserFragment
}
答案 0 :(得分:0)
您正在尝试注入仅在User
中的@UserScope
中提供的@FragmentScope
实例。
基本上,规则是每当您需要User
注入时 - 您需要加入@UserScope
。
您需要在所有地方更改@FragmentScope
到@UserScope
注释。
根据您发布的内容,我相信它就在这里:
@Module
class UserFragmentModule {
@Provides
@UserScope
fun provideViewModelFactory(someModule: SomeModule) = UserFragmentViewModelFactory(someModule)
}
您需要将UserFragmentModule
移至UserComponent
:
@UserScope
@Subcomponent(
modules = [UserModule::class, UserFragmentModule::class]
)
interface UserComponent {
而且您还需要将application.userComponent
注入UserFragment
这是一个很好的article about subcomponents。我建议你阅读它以获得充分的理解。
另一种选择,我不确定这个,但也许你可以用你的application.userComponent
注入你的UserFragment。
答案 1 :(得分:0)
我认为您的问题是使用范围错误。 范围帮助我们处理注入的项目生命周期,以防止在整个应用程序生命周期中保持不需要的对象。
并查看此图片:
您的模块应与组件的范围相同。
例如,在AppComponent
中,ActivityBindingModule
有ActivityScope
。你为什么这样做?
我认为最好让activityComopnent
依赖appComponent
。如果您的activityComponent在上限范围组件(appComponent)中具有某些依赖关系,则首先添加该组件的依赖关系。 (dependencies= [ AppComponent::class]
)。其次,您必须使用返回所需依赖项对象的方法在appComponent中公开所需的依赖项。最后在wireUpping中,你应该在Dagger wire upping中调用appComponent作为调用活动模块。 (我将在一个例子中显示这个)
所以你需要的就是这样的activityComponent:
@ActivityScope
@Component(modules = [ActivityBindingModule::class],dependencies= [ AppComponent::class])
interface activityComponent {
.
.
.
这是我用java编写的示例,它显示了如何连接 appComponent 和 activityComponent :
@Singleton
@Component(modules = {ApplicationModule.class ,ServicesModule.class})
public interface ApplicationComponent {
void inject(ImicoApplication imicoApplication);
// exposed for child-components.
Context getContext();
Application getApplication();
CompanyService getCompanyService();
CategoryService getCategoryService();
RatingService getRatingService();
NewsService getNewsService();
AuthorizationManager getAuthorizationManager();
}
这是 activityComponent :
@ActivityScope
@Component(dependencies = {ApplicationComponent.class},modules = {SearchActivityModule.class})
public interface SearchserviceComponent {
void inject (SearchFragment searchFragment);
}
在SearchFragment中执行此操作以进行连线:
DaggerSearchserviceComponent.builder()
.applicationComponent(((ImicoApplication) getActivity().getApplication()).getApplicationComponent())
.searchActivityModule(new SearchActivityModule(this)).build().inject(this);
如果在SearchFragment中我需要 CompanyService ,只需注入它,它就会被applicationComponent
提供并公开。