Dagger:是否可将Subcomponent的Getter自动暴露给兄弟子组件的作用域?
解决方案
这个需求完全可以实现,用Dagger原生的**组件依赖(Component Dependencies)**特性就能完美匹配你的要求,无需引入额外工具,同时可以严格保证A和B的隔离性。
改造步骤
你只需要做少量修改替换原有实现:
- 修改B组件的
@Component注解,声明依赖A组件
// 原有注解只需要新增dependencies参数 @Component(modules = {你的B组件原有Module列表}, dependencies = A.class) @BScope // 如果B有自定义作用域需要保留 public interface B { // 原有B的其他代码不变 @B Q getQ(); }
- 清空B组件Builder中所有针对A暴露对象的
@BindsInstance方法,仅保留一个传入A实例的方法
@Component.Builder interface Builder { // 原有B需要的其他绑定方法保留,只删A相关的@BindsInstance Builder a(A aComponent); // 原有build方法保留 B build(); }
- 简化B组件的构建代码,删除所有手动bind逻辑
Root rootComponent = buildRootComponent(); A aComponent = rootComponent.getAComponentBuilder().build(); // 无需逐个绑定A的暴露接口,直接传入A实例即可 B bComponent = rootComponent.getBComponentBuilder() .a(aComponent) .build();
效果说明
改造完成后,你后续新增A到B的共享对象时,只需要做一步操作:在A的接口中添加对应的Getter方法(和B中注入点的限定符、类型完全匹配即可),完全不需要修改B的Builder、也不需要添加额外的粘合代码,Dagger会自动完成绑定。
同时B只能访问A接口中显式声明的Getter方法返回的对象,A的其他内部内容对B完全不可见,符合你要求的隔离规则。
注意事项
- A的Getter方法上的限定符注解(比如示例中的
@B)需要和B中对应依赖的注入点注解完全一致 - 如果A的暴露对象带有自定义作用域(比如
@AScope),需要在B的@Component注解上声明可识别该作用域,避免编译报错
内容的提问来源于stack exchange,提问作者dave mankoff
相关产品推荐
相关产品推荐

