Add*_*dev 6 java android dependency-injection dagger dagger-2
如何在Dagger 2的不同范围内覆盖依赖关系?例:
我的应用程序中有两个组件:ApplicationComponent和ActivityComponent.ApplicationComponent是基本组件,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");
}
}
Run Code Online (Sandbox Code Playgroud)
和代码:
ApplicationComponent applicationComponent = DaggerApplicationComponent.builder().build();
applicationComponent.provideParrot().sayHello();
activityComponent = DaggerActivityComponent.builder()
.applicationComponent(applicationComponent).build();
activityComponent.provideParrot().sayHello();
Run Code Online (Sandbox Code Playgroud)
我想要的输出是:
Hello Application
Hello Activity
Run Code Online (Sandbox Code Playgroud)
所以我制作了模块:
ApplicationModule:
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
但是使用此配置,输出为:
Hello Application
Hello Application
Run Code Online (Sandbox Code Playgroud)
我做错了什么?谢谢
简短的答案是...您无法做到。
使用匕首,一切都在编译时完成。
您有一个应用程序组件,该组件知道如何构造HelloPrinter和Parrot。
然后,公开Parrot供所有组件使用。
您拥有活动组件,该组件也知道如何构造HelloPrinter!
那会怎样呢?
请记住对象图。组件知道它们可以构建什么,并依赖于其他组件,从而公开已知的对象。
applicationComponent.provideParrot().sayHello();
Run Code Online (Sandbox Code Playgroud)
这很容易。您创建组件,想要一个鹦鹉,它是使用已知的打印机构造的。
activityComponent.provideParrot().sayHello();
Run Code Online (Sandbox Code Playgroud)
这里发生的(基本上)是相同的。你说你想要一只鹦鹉。您的活动组件不知道如何制造打印机,只知道如何制造打印机!
可是等等。它依赖于应用程序组件,可以方便地公开ParrotFactory。
调用应用程序组件工厂,并实例化鹦鹉。由于应用程序模块知道如何构建打印机,因此它会使用手头的打印机。
...怎么办
所以...您可以在活动组件中提供鹦鹉,然后他们将使用其他打印机!
Gradle:错误:鹦鹉被绑定多次
在这里,由于没有“覆盖”发生,因此我们将2个鹦鹉放入对象图。这行不通,也不应该。
结论
没有方法可以覆盖方法。一旦声明一秒钟,Parrot否则HelloPrinter编译将失败。
要实现类似功能,唯一的可能性是在要使用的@Named()打印机上使用注释,并且/或者将整个鹦鹉创建工作放到活动模块中。
并且,如果我缺少某些内容,请更正我,但我什至看不到使用命名注释使签名保持相同的方法。
| 归档时间: |
|
| 查看次数: |
1438 次 |
| 最近记录: |