如何在匕首2中覆盖范围内的依赖关系



如何覆盖Dagger 2不同范围内的依赖关系?示例:

我的应用程序中有两个组件:ApplicationComponentActivityComponentApplicationComponent是基本组件,ActivityComponent是我要执行覆盖的作用域组件。

对于这个例子,我创建了以下模型:

public class Parrot {
    private final HelloPrinter helloPrinter;
    public Parrot(HelloPrinter helloPrinter) {
        this.helloPrinter = helloPrinter;
    }
    public void sayHello(){
        helloPrinter.print();
    }
}

public interface HelloPrinter {
    void print();
}

public class AppHelloPrinter implements HelloPrinter{
    @Override
    public void print() {
        System.out.println("Hello Application");
    }
}
public class ActivityHelloPrinter implements HelloPrinter {
    @Override
    public void print() {
        System.out.println("Hello Activity");
    }
}

代码:

ApplicationComponent applicationComponent = DaggerApplicationComponent.builder().build();
applicationComponent.provideParrot().sayHello();
activityComponent = DaggerActivityComponent.builder()
                        .applicationComponent(applicationComponent).build();
activityComponent.provideParrot().sayHello();

我想要的输出是:

Hello Application
Hello Activity

所以我制作了模块:

应用程序模块:

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
    Parrot provideParrot();
}
@Module
public class ApplicationModule {
    @Provides
    @Singleton
    HelloPrinter providePrinter(){
        return new AppHelloPrinter();
    }
    @Provides
    Parrot provideParrot(HelloPrinter helloPrinter) {
        return new Parrot(helloPrinter);
    }
}

ActivityModule:试图覆盖HelloPrinter

@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class)
public interface ActivityComponent {
    Parrot provideParrot();
}
@Module
@PerActivity
public class ActivityModule {
    @Provides
    @PerActivity
    HelloPrinter provideHelloPrinter() {
        return new ActivityHelloPrinter();
    }     
}

但使用此配置,输出为:

Hello Application
Hello Application

我做错了什么?感谢

简单的答案是……你不能这么做。

有了dagger,一切都在编译时完成。

  1. 您有一个应用程序组件,它知道如何构造HelloPrinterParrot
    然后公开Parrot供所有组件使用。

  2. 你有你的活动组件,它也知道如何构建HelloPrinter

那么会发生什么呢

请记住对象图。组件知道它们可以构建什么,并依赖于其他组件,从而公开已知对象本身。

applicationComponent.provideParrot().sayHello();

这个很简单。你创建了组件,你想要一个鹦鹉,它是使用已知的打印机构建的。

activityComponent.provideParrot().sayHello();

这里发生的事情(基本上)是一样的。你说你想要一只鹦鹉。你的活动组件不知道如何制作,它只知道如何制作打印机
但是等一下它依赖于一个应用程序组件,方便地公开了一个Parrot工厂。

调用应用程序组件工厂,并实例化鹦鹉。由于应用程序模块知道如何构建打印机,因此它使用手头的打印机。

。。。现在是什么

所以。。。你可以在你的活动组件中提供鹦鹉,然后它们会使用不同的打印机!

Gradle:错误:Parrot多次绑定

在这里,我们将把2个鹦鹉放入我们的对象图中,因为没有发生"覆盖"。这行不通,也不应该。

结论

无法覆盖方法。一旦您声明第二个ParrotHelloPrinter,它将无法编译。

实现类似功能的唯一可能是在要使用的打印机上使用@Named()注释和/或将整个鹦鹉创建下拉到活动模块中。

如果我遗漏了什么,请纠正我,但我甚至看不到使用命名注释来保持签名不变的方法。

最新更新