Android中Dagger2注入HouseInterface失败,依赖实现类正常,求解决
解决Dagger2中接口注入的问题
我来帮你搞定这个问题!你现在遇到的核心问题是WarComponent不知道如何提供HouseInterface的实例,而且成员变量的注入需要显式触发。咱们一步步来修正:
问题根源分析
- 你的
WarComponent没有关联任何能提供HouseInterface的Module或Component,所以Dagger只认识有@Inject构造函数的类(比如War和Stark),但不知道HouseInterface和Stark的绑定关系。 - 就算绑定关系存在,仅通过
component.getWar()创建War实例,只会触发构造函数的注入,不会自动初始化类中的@Inject成员变量,必须显式调用inject()方法完成这一步。
解决方案步骤
1. 让WarComponent关联HouseModule
修改WarComponent,把HouseModule加入到它的modules列表中,这样Dagger就能知道HouseInterface的实现是Stark:
@Component(modules = HouseModule.class) public interface WarComponent { War getWar(); void inject(War war); // 保留这个方法用于成员变量注入 }
如果想保持组件的独立性,也可以让WarComponent依赖HouseComponent:
@Component(dependencies = HouseComponent.class) public interface WarComponent { War getWar(); void inject(War war); }
2. 优化HouseModule(可选但推荐)
把@Provides换成@Binds,这是Dagger推荐的绑定接口与实现类的方式,生成的代码更高效:
@Module public abstract class HouseModule { @Binds public abstract HouseInterface bindHouse(Stark stark); }
注意:用
@Binds的话,Module必须是抽象类,而且依赖的实现类(这里是Stark)必须有@Inject构造函数,你的代码已经满足这个条件了。
3. 修改测试代码,触发成员注入
在测试中,创建War实例后,必须调用component.inject(war)来初始化HouseInterface成员变量:
@Test public void printNameTest() { String expected = "stark"; // 如果是直接关联HouseModule的方式 WarComponent component = DaggerWarComponent.create(); War war = component.getWar(); component.inject(war); // 关键:触发成员变量注入 // 如果是依赖HouseComponent的方式 // HouseComponent houseComponent = DaggerHouseComponent.create(); // WarComponent warComponent = DaggerWarComponent.builder() // .houseComponent(houseComponent) // .build(); // War war = warComponent.getWar(); // warComponent.inject(war); Assert.assertEquals(war.getHouseName(), expected); }
4. 保持War类的依赖抽象
你的War类代码可以保留#1的方式,不需要依赖具体的Stark类:
public class War { @Inject public War() { } @Inject HouseInterface houseInterface; // 这个现在可以正常工作了 public String getHouseName() { return houseInterface.sayHello(); } }
这样修改后,War类就只依赖HouseInterface接口,完全符合你的需求了!
内容的提问来源于stack exchange,提问作者Mohammad Ranjbar Z
相关产品推荐
相关产品推荐

