在匕首2作用域 [英] Scopes in Dagger 2

查看:147
本文介绍了在匕首2作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可能错过了一些东西,但我认为作用域像@辛格尔顿被用来定义范围内的生命周期。

我用匕首2在一个Android应用程序(但我不认为这个问题是机器人在所有相关的)。

我有1模块:

  @Module公共类MailModule {

  @辛格尔顿@Provides公众的AccountManager providesAccountManager(){
    返回新的AccountManager();
  }

  @辛格尔顿@Provides公共MailProvider providesMailProvider(的AccountManager的AccountManager){
    返回新MailProvider(的AccountManager);
  }
}
 

我有两个不同的组件 @Singleton 范围:

  @Singleton
@Component(模块= MailModule.class)
公共接口LoginComponent {

  市民登录presenter presenter();
}


@Singleton
@零件(
    模块= MailModule.class
)
公共接口MenuComponent的{

  菜单presenter presenter();

}
 

在这两方面,菜单presenter 登录presenter ,有一个 @Inject 的构造。虽然菜单presenter预计 MailProvider 作为参数,登录presenter需要一个的AccountManager

  @注入公共菜单presenter(MailProvider mailProvider){...}

  @注入公共登录presenter(的AccountManager的AccountManager){...}
 

但每次我用组件来创建一个菜单presenter时间登录presenter 我得到 MailProvider 的AccountManager 的一个全新的实例。我以为他们是在同一范围内,因此应该是一种单例(在相同的范围内)。

难道我明白的东西完全错误的。在匕首2如何定义一个真正的单身多个部件?

解决方案

我认为 LoginComponent MenuComponent中是单独使用,例如在 LoginActivity MenuActivity 。每个组件内置在 Activity.onCreate 。如果是这样,组件重新创建,模块和依赖性过每一次新的活动,独立的适用范围是什么,他们的债券的。因此,你得到的新实例 MainProvider 的AccountManager 每次

MenuActivity LoginActivity 有单独livecycles,所以从 MailModule 不能单在两人面前。你需要的是申报根组件与 @Singleton 范围(例如,在应用程序子类),使 MenuComponent中 LoginComponent 依赖于它。活动水平组件不能@Singleton范围,更好地使用 @Scope 注释,创建自己的范围,例如:

  @Retention(RetentionPolicy.RUNTIME)
@范围
公共@interface MenuScope {
}
 

或者你也可以让他们无范围。

对于范围都在这里是从最初简单的<一个href="https://docs.google.com/document/d/1fwg-NsMKYtYxeEWe82rISIHjNrtdqonfiHgp8-PQ7m8/edit#heading=h.5xwubel5z6iq"相对=nofollow>匕首2提议:

  @Singleton
@Component(模块= {...})
公共接口ApplicationComponent {}
 

这声明允许匕首强制执行以下限制:

     
      
  • 在一个给定的组件可能只有绑定(包括类范围注释)是无范围的申报范围或。   即一个组件不能再present两个作用域。如果没有范围   上市,绑定只能在无范围。
  •   
  • 系统范围的组件可能只有一个范围依赖。这是强制执行两个组件并非每个申报机制   自己的作用域确定为具有约束力。例如。两个单件组件,每个都具有   自己@Singleton缓存会被打破。
  •   
  • 的范围为组件不能出现在其任何传递依赖。例如:SessionScoped - > RequestScoped - > SessionScoped   没有任何意义,是一个错误。
  •   
  • @Singleton是专门的,因为它不能有任何范围依赖性治疗。每个人都希望辛格尔顿是根。
  •   
     

的规则这一组合的目标是执行,当范围是   施加,组分与我们所使用的相同的结构组成   有一个与匕首1.0加()处理ObjectGraphs,但与能力   所有的绑定和其范围的静态知识。放在   另一种方式,当范围被施加,这限制了图形比   可以建立只有那些可以正确构建

这是我自己的实践,它更清晰不使用 @Singleton 可言。取而代之的是,我用 @ApplicationScope 。它的作用是定义在整个应用程序的单身,没有额外的限制 @Singleton 了。

希望可以帮助您:)。这是相当棘手的,可以迅速了解,需要时间的,至少对我来说那是。

I probably missed something, but I thought Scopes like @Singleton are used to define "scoped lifecycles".

I use Dagger 2 in an Android app (but I don't think the problem is android related at all).

I have 1 Module:

@Module public class MailModule {

  @Singleton @Provides public AccountManager providesAccountManager() {
    return new AccountManager();
  }

  @Singleton @Provides public MailProvider providesMailProvider(AccountManager accountManager) {
    return new MailProvider(accountManager);
  }
}

I have two different components with @Singleton scope:

@Singleton
@Component(modules = MailModule.class)
public interface LoginComponent {

  public LoginPresenter presenter();
}


@Singleton
@Component(
    modules = MailModule.class
)
public interface MenuComponent {

  MenuPresenter presenter();

}

Both, MenuPresenter and LoginPresenter, have an @Inject constructor. While MenuPresenter expects MailProvider as parameter, LoginPresenter takes an AccountManager:

  @Inject public MenuPresenter(MailProvider mailProvider) { ... }

  @Inject public LoginPresenter(AccountManager accountManager) { ... }

But every time I use the components to create a MenuPresenter or LoginPresenter I get a fresh new instance of MailProvider and AccountManager. I thought they were in the same scope and should therefore be kind of singleton (in the same scope).

Did I understand something completely wrong. How do I define a real singleton for multiple components in dagger 2?

解决方案

I assume that LoginComponent and MenuComponent are used separately, e.g. in LoginActivity and MenuActivity. Each component is built in Activity.onCreate. If so, components are recreated every time new activity created, modules and dependencies too, independent of what scope they bond to. Therefore, you get new instances of MainProvider and AccountManager every time.

MenuActivity and LoginActivity have separate livecycles, so dependencies from MailModule cannot be singleton in both of them. What you need is to declare root component with @Singleton scope (e.g. in Application subclass), make MenuComponent and LoginComponent depend on it. Activity level component cannot be @Singleton scoped, better to create your own scopes using @Scope annotation, e.g.:

@Retention(RetentionPolicy.RUNTIME)
@Scope
public @interface MenuScope {
}

Or you can leave them unscoped.

Regarding scopes at all here's brief from initial Dagger 2 proposal:

@Singleton
@Component(modules = {…})
public interface ApplicationComponent {}

That declaration enables dagger to enforce the following constraints:

  • A given component may only have bindings (including scope annotations on classes) that are unscoped or of the declared scope. I.e. a component cannot represent two scopes. When no scope is listed, bindings may only be unscoped.
  • A scoped component may only have one scoped dependency. This is the mechanism that enforces that two components don’t each declare their own scoped binding. E.g. Two Singleton components that each have their own @Singleton Cache would be broken.
  • The scope for a component must not appear in any of its transitive dependencies. E.g.: SessionScoped -> RequestScoped -> SessionScoped doesn’t make any sense and is a bug.
  • @Singleton is treated specially in that it cannot have any scoped dependencies. Everyone expects Singleton to be the "root".

The goal of this combination of rules is to enforce that when scope is applied, components are composed with the same structure that we used to have with Dagger 1.0 plus()’d ObjectGraphs, but with the ability to have static knowledge of all of the bindings and their scopes. To put it another way, when scopes are applied, this limits the graphs than can be built to only those that can be correctly constructed.

From my own practice, it's clearer not to use @Singleton at all. Instead of that, I use @ApplicationScope. It serves to define singletons on whole application and does not have additional restrictions as @Singleton has.

Hope that helps you :). It's quite tricky to be understood quickly, takes time, for me at least it was.

这篇关于在匕首2作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆