soc*_*qwe 26 java android dagger-2
我可能错过了一些东西,但我认为像@Singleton这样的Scopes用来定义"范围生命周期".
我在Android应用程序中使用Dagger 2(但我不认为这个问题与Android有关).
我有1个模块:
@Module public class MailModule {
@Singleton @Provides public AccountManager providesAccountManager() {
return new AccountManager();
}
@Singleton @Provides public MailProvider providesMailProvider(AccountManager accountManager) {
return new MailProvider(accountManager);
}
}
Run Code Online (Sandbox Code Playgroud)
我有两个不同的组件,@Singleton
范围:
@Singleton
@Component(modules = MailModule.class)
public interface LoginComponent {
public LoginPresenter presenter();
}
@Singleton
@Component(
modules = MailModule.class
)
public interface MenuComponent {
MenuPresenter presenter();
}
Run Code Online (Sandbox Code Playgroud)
两者都有,MenuPresenter
并且LoginPresenter
有一个@Inject
构造函数.虽然MenuPresenter期望MailProvider
作为参数,但LoginPresenter需要AccountManager
:
@Inject public MenuPresenter(MailProvider mailProvider) { ... }
@Inject public LoginPresenter(AccountManager accountManager) { ... }
Run Code Online (Sandbox Code Playgroud)
但每次我使用组件创建一个MenuPresenter
或LoginPresenter
我得到一个新的MailProvider
和新的实例AccountManager
.我认为它们属于同一范围,因此应该是单一的(在同一范围内).
我是否完全理解了一些错误.如何在匕首2中为多个组件定义真正的单例?
Kir*_*nov 51
我假设LoginComponent
并且MenuComponent
单独使用,例如在LoginActivity
和中MenuActivity
.每个组件都是内置的Activity.onCreate
.如果是这样,每次创建新活动时,都会重新创建组件,模块和依赖项,而与它们所绑定的范围无关.因此,你得到的新情况MainProvider
和AccountManager
每一次.
MenuActivity
并且LoginActivity
具有单独的livecycles,因此依赖关系MailModule
不能在它们中都是单例.你需要的是用@Singleton
范围声明根组件(例如在Application子类中),make MenuComponent
并LoginComponent
依赖它.活动级别组件不能是@Singleton作用域,更好的是使用@Scope
注释创建自己的作用域,例如:
@Retention(RetentionPolicy.RUNTIME)
@Scope
public @interface MenuScope {
}
Run Code Online (Sandbox Code Playgroud)
或者你可以让他们不受约束.
关于范围,根据最初的Dagger 2提案的简要说明:
Run Code Online (Sandbox Code Playgroud)@Singleton @Component(modules = {…}) public interface ApplicationComponent {}
该声明使匕首能够执行以下约束:
- 给定组件可能只有未绑定或声明范围的绑定(包括类的范围注释).即组件不能代表两个范围.如果未列出范围,则绑定可能仅为未范围.
- 范围组件可能只有一个范围依赖项.这是一种机制,强制两个组件不会各自声明自己的作用域绑定.例如,每个拥有自己的@Singleton Cache的两个Singleton组件都将被破坏.
- 组件的范围不得出现在其任何传递依赖项中.例如:SessionScoped - > RequestScoped - > SessionScoped没有任何意义,是一个错误.
- @Singleton的特殊处理方式是它不能有任何作用域依赖项.每个人都希望Singleton成为"根".
这种规则组合的目标是强制执行范围应用时,组件使用与Dagger 1.0 plus()'d ObjectGraphs相同的结构,但能够具有所有的静态知识.绑定及其范围.换句话说,当应用范围时,这限制了图形,而不是仅构建可以正确构造的图形.
从我自己的实践来看,根本不使用它更清楚@Singleton
.而不是那样,我用@ApplicationScope
.它用于在整个应用程序中定义单例,并且没有其他限制@Singleton
.
希望能帮到你:).快速理解是非常棘手的,需要时间,至少对我而言.
您可以执行以下操作来为多个组件定义实际单例.我假设@ApplicationScoped
并且@ActivityScoped
是不同的范围.
@Module public class MailModule {
@Provides @ApplicationScoped
public AccountManager providesAccountManager() {
return new AccountManager();
}
@Provides @ApplicationScoped
public MailProvider providesMailProvider(AccountManager accountManager) {
return new MailProvider(accountManager);
}
}
Run Code Online (Sandbox Code Playgroud)
然后MailComponent
可以定义一个MailModule
.该LoginComponent
和MenuComponent
可以依靠的MailComponent
.
@ApplicationScoped
@Component(modules = MailModule.class)
public interface MailComponent {
MailProvider mailProvider();
AccountManager accountManager();
}
@ActivityScoped
@Component(dependencies = MailComponent.class)
public interface LoginComponent {
LoginPresenter presenter();
}
@ActivityScoped
@Component(dependencies = MailComponent.class)
public interface MenuComponent {
MenuPresenter presenter();
}
Run Code Online (Sandbox Code Playgroud)
在MailComponent
如下图所示,可以用在可被初始化MenuComponent
和LoginComponent
下面再次示出.
MailComponent mailComponent = DaggerMailComponent.builder().build();
DaggerMenuComponent.builder().mailComponent(mailComponent).build();
DaggerLoginComponent.builder().mailComponent(mailComponent).build()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
13208 次 |
最近记录: |