Dagger 2如何到处访问相同的组件

时间:2018-03-28 14:27:11

标签: android dagger-2

如何创建一个单例对象,我可以从代码中的任何位置访问该对象?

  • 无法使用匕首创建我想要注射我的signleton组件的对象(1)。
  • 这些对象没有我可以访问的公共依赖项(例如getApplication()

快速举例:

InjectedClass

public class InjectedClass {
    public InjectedClass() {
        System.out.println("injected class created");
    }
}

HolderClassA

public class HolderClassA { // this is one of object I marked with (1)
    @Inject InjectedClass b;
    public HolderClassA() {
        Injector build = DaggerInjector.builder().build();
        build.inject(this);
        System.out.println(b);
    }
}

HolderClassB

public class HolderClassB { // this is another object I marked with (1)
    @Inject InjectedClass b;
    public HolderClassB() {
        Injector build = DaggerInjector.builder().build();
        build.inject(this);
        System.out.println(b);
    }
}

提供商

@Module
public class Provider {

    @Provides
    @Singleton
    InjectedClass provideInjectedClass() {
        return new InjectedClass();
    }
}

注射器

@Component(modules = {Provider.class})
@Singleton
public interface Injector {

    void inject(HolderClassA a);
    void inject(HolderClassB a);

}

代码中的某处

new HolderClassA();

代码中的其他地方,与先前的代码无关,也没有相同的父级或可以访问相同的对象(例如带有getApplication()的匕首指南):

new HolderClassB();

实际结果:两个的InjectedClass实例是装箱

预期结果:创建了InjectedClass单个实例。

问题是DaggerInjector.builder().build();创建了彼此不了解的不同范围。例如,我可以通过创建静态变量DaggerInjector.builder().build()并从中调用inject来解决此问题。但是因此它不再是依赖注入,而是不是琐碎的单例模式。

1 个答案:

答案 0 :(得分:1)

根据我对评论的理解,您希望持有者类的单独组件会注入相同的实例吗?如果我错了,请原谅我。 你可以试试这个。

@Component(modules = arrayOf(AppModule::class))
@Singleton
interface AppComponent {
    //sub components
    fun plusHolderClass1(holderModule: HolderModule1):HolderComponent1
    fun plusHolderClass2(holderModule: HolderModule2):HolderComponent2    
    //provision methods
    fun getInjectedClass():InjectedClass
}

这是您在应用程序中初始化的应用程序组件或顶级组件,当然使用Module类将Injected类提供为单例。

@Subcomponent(modules = arrayOf(HolderModule1::class))
@ActivityScope
interface HolderComponent1{
    fun inject(holder:Holder1)
}

与Holder2类相似。您可以在模块中定义本地范围依赖项。

但是,当然即使在这种情况下,您也必须在Application类中存储appComponent的实例。

注射时

appComponent.plusHolderComponent1(HolderModule1()).inject(yourObject)

通过从提供方法

获取InjectedClass对象,将其注入到对象中