匕首2单例在多个实例 [英] Dagger 2 singleton in multiple instances

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

问题描述

我刚刚测试了匕首2,我对单例注释有一些奇怪的行为。我创建了一些测试代码来显示我的问题。

I just tested out Dagger 2 and I am having some strange behaviour regarding the singleton annotation. I created some test code to show my problem.

我的模块:

@Module
public class App {

    @Provides
    @Singleton
    ThingA provideThingA(){
        return new ConcreteThingA();
    }

}

我想要的东西的界面单例:

Interface of the thing I want in singleton:

public interface ThingA {
    void showMyId();
}

实施:

public class ConcreteThingA implements ThingA {
    @Override
    public void showMyId() {
        System.out.println(this);
    }
}

执行匕首的代码:

public void doStuff() {
    ThingA thingA=DaggerThingAComponent.create().provideThingA();
    ThingA thingB=DaggerThingAComponent.create().provideThingA();
    System.out.println("Hello");
}

这里是一个截图,显示当我没有得到相同的实例要求两次我错过了一些基本的东西吗? ThingA只是一个愚蠢的名字,在我的实际应用中,我希望在我的服务中有这种单身份的行为。

And here is a screenshot showing that I do not get the same instance when I ask for it twice. Have I missed something fundamental? ThingA is just a silly name and in my actual application I would like to have this singleton behaviour on my services.

推荐答案

诀窍是Dagger通过组件实现范围/生命周期,并且您在此创建了两个单独的组件:

The trick is that Dagger enforces scope/lifecycle through components, and you've created two separate components here:

ThingA thingA = DaggerThingAComponent.create().provideThingA();
ThingA thingB = DaggerThingAComponent.create().provideThingA();

每次创建新的顶级@ Singleton注释组件时,Dagger创建一个全新的对象图形与每个@Singleton对象的全新容器。你应该改为:

Each time you create the new top-level @Singleton-annotated Component, Dagger creates a brand new object graph with a brand new container for each @Singleton object. You should have this instead:

ThingAComponent component = DaggerThingAComponent.create();
ThingA thingA = component.provideThingA();
ThingA thingB = component.provideThingA();  // thingA == thingB

当然,通过依赖图进一步访问的任何东西都来自于组件,所以这将保留您要查找的单身人士行为。

Of course, anything further accessed through the dependency graph all comes from the same component, so this will preserve the singleton behavior you're looking for.

在大多数情况下,您不需要传递组件:组件应用于顶级组件,任何可通过注入器访问的内容应该@注入其依赖项(这意味着它不应该需要对组件本身的引用)。这在迁移到DI或Dagger期间可能会出现问题,但是创建多个@Singleton组件并不是围绕它的方式。相反,请尝试以下方法之一:

In most cases, you should not need to pass around the Component: The Component should be used for top-level components, and anything accessible through the injector should @Inject its dependencies (which means it shouldn't need a reference to the component itself). This might appear problematic during the migration to DI or Dagger, but creating multiple @Singleton components is not the way around it. Instead, try one of the following:


  • 如果您需要多个实例,您可以随时注入 Provider<无论您是否创建了 @Provides 方法,而不是 T 。对于这个问题,如果你只需要零个或一个拷贝的特定依赖关系,你可以注入一个 Lazy< T> ,特别是如果该对象的创建特别重。 / li>
  • 如果您在对象图中需要深入,您可以@注入组件本身,但始终优先于 @Inject Provider< T> tProvider 而不是 @Inject YourComponent 只需调用 YourComponent.getT

  • 在某些情况下,包括Android,将组件保存到全局可访问的字段(作为应用程序中的实例字段)或其他位置的静态字段可能是有意义的。这是因为Android自动创建对象,而不是从图形中注入实例。对于所有其他情况,请注意您的依赖关系,以避免需要传递组件。

  • If you need multiple instances of something, you can always inject Provider<T> instead of T whether or not you've created a @Provides method. For that matter, you can inject a Lazy<T> if you only need zero or one copies of a particular dependency, particularly if the creation of that object is particularly heavy.
  • You can @Inject the component itself if you need it deep within the object graph, though it's always preferable to @Inject Provider<T> tProvider instead of @Inject YourComponent just to call YourComponent.getT.
  • In some cases, including Android, it may make sense to save the component to a globally-accessible field, either as an instance field in your Application or as a static field somewhere else. This is specifically because Android creates objects on its own, reflectively, rather than getting injected instances from the graph. For all other cases, inject your dependencies to avoid needing to pass around the component.

另请参见:图形中的绑定来自匕首2用户指南

See also: Bindings in the graph from the Dagger 2 Users Guide

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

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