我有一个域实体 - 我们假设它是Car
- 它包含我通过Dagger注入的存储库实现。当我测试我的实体时,我将存储库替换为模拟实现。 Car
也implements Parcelable
。
Dagger可以在调用Car(Engine)
时构造对象,但是当调用Car(Parcel)
时它显然无法执行,因为它是由Parcelization Framework在内部调用的(通常是从Car
获取Intent
时Car(Parcel)
)。
在Parcel
构造函数中手动注入依赖项是一个好主意吗?或者,您可以推荐最佳做法吗?在public class Car implements Parcelable {
@Inject ICarRepository CarRepositoryImpl;
private Engine engine; // User specified engine passed through constructor
public Car(Engine engine) {
this.engine = engine;
}
public Car(Parcel parcel) {
this.engine = getEngine(parcel); // Read engine from parcel
// Inject dependencies here?
}
// Static Parcelable creator and other methods follow...
}
构造函数中注入依赖项肯定会解决我的问题,但建议不要在构造函数中注入依赖项,以便在实例化和注入逻辑之间保持关注点分离。
这是我的域名实体
{{1}}
答案 0 :(得分:3)
David对您的问题发表了评论 - 为什么Car
会依赖CarRepository
?这绝对是一种反模式 - 存储库用于将实体与建模/持久性分离;在这里你介绍一个看似没有任何理由。但是,让我们假设您只是为了举例而将存储库放在那里。
当然,Dagger没有自动的方法来准备一个被取消的对象。这意味着,我们必须在某个地方调用Dagger。
根据我的判断,合适的候选人将是您的public static final Parcelable.Creator CREATOR
,如下:
// Creator
public static final Parcelable.Creator<Car> CREATOR
= new Parcelable.Creator<>() {
public Car createFromParcel(Parcel in) {
Car ret = new Car(in);
DaggerCarComponent.builder().build().inject(ret);
return ret;
}
};
使用此技术取得的目标
Car
实例化Parcel
。@Component
,您的代码不仅可以抵御未来的更改(例如添加或删除依赖项),还可以使用极简主义/ DRY 答案 1 :(得分:0)
一种可能的解决方案是所谓的“可拆分注入模式”: https://medium.com/@felix.kirchengast/mocking-intents-the-parcelable-injection-pattern-88be4abcccb3
这意味着要覆盖静态CREATOR对象,类似于静态依赖项注入。