Is it possible to avoid unnecessary injection in parent class?
给出以下示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class CustomView extends View { @Inject SomeObject mObject; @Override protected void onFinishInflate() { super.onFinishInflate(); getApplicationComponent().inject(this); } } class SecondaryCustomView extends CustomView { @Inject AnotherObject mAnotherObject; @Override protected void onFinishInflate() { super.onFinishInflate(); getApplicationComponent().inject(this); } } |
两个自定义视图都可以在布局上独立使用。第二个只比第一个更专业。
如您所见,这两个域都有要注入的字段,并且都需要调用inject()。问题在于,当SecondaryCustomView调用其inject()时,Dagger会注入AnotherObject的实例和SomeObject的实例。调用super.onFinishInflate()之后,它将创建SomeObject的第二个实例。这本身不是问题,但是我们至少正在创建不必要的对象。
有办法避免这种情况吗?通过某种方式告诉Dagger已注入了子类,因此忽略父注入?
作为示例,该组件如下所示:
1 2 3 4 5 | @Component(...) public interface AppComponent { void inject(CustomView); void inject(SecondaryCustomView); } |
在Dagger中无法执行此操作,但是您可以自己执行。
要同意并扩大您在评论中的观点:
yes it is needed. Dagger does not inject the child objects if we use injection on parent only. however it injects the parent objects if it is called from the child.
这是正确的,并在"有关协方差的注释"中进行了说明:尽管
除了简单地将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | class CustomView extends View { @Inject SomeObject mObject; @Override protected void onFinishInflate() { injectMe(); super.onFinishInflate(); } protected void injectMe() { getApplicationComponent().inject(this); // inject(CustomView); } } class SecondaryCustomView extends CustomView { @Inject AnotherObject mAnotherObject; @Override protected void onFinishInflate() { super.onFinishInflate(); // ... } /** Despite looking identical, the JVM can call the more-specific overload here. */ @Override protected void injectMe() { getApplicationComponent().inject(this); // inject(SecondaryCustomView) } } |
如果您正在寻找针对Activity和Fragment类的类似解决方案,则可以使用dagger.android;那里的内置机制使用类的运行时类型从Map动态获取正确的AndroidInjector。但是,该解决方案目前不支持View,因此与您的特定情况相近。