【问题标题】:How to inject an object using a value obtained in an activity?如何使用在活动中获得的值注入对象?
【发布时间】:2019-09-06 14:22:44
【问题描述】:

我有一个活动,我通过 Firebase 身份验证获取用户的 uid

public class MainActivity extends DaggerAppCompatActivity {
     @Inject UserViewModel userViewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
        userViewModel.setUid(uid);
    }
}

我在我的视图模型类中使用了这个uid

public class UserViewModel extends ViewModel {
    private CollectionReference usersRef;

    @Inject
    UsersViewModel(CollectionReference usersRef) {
        this.usersRef = usersRef;
    }

    void setUid(String uid) {
        DocumentReference uidRef = usersRef.document(uid);
        //Use uidRef
    }
}

这是我的应用模块类:

class AppModule {
    @Singleton
    @Provides
    static FirebaseFirestore provideFirebaseFirestoreInstance() {
        return FirebaseFirestore.getInstance();
    }

    @Singleton
    @Provides
    static CollectionReference provideUsersCollectionRef(FirebaseFirestore db) {
        return db.collection("users");
    }

    @Singleton
    @Provides
    static DocumentReference provideUidDocumentRef(CollectionReference usersRef) {
        return usersRef.document(uid); //How to add the uid here
    }
}

问题是,如何在应用模块类中添加uid,这样我就可以像这样直接在我的视图模型类中注入 DocumentReference:

public class UserViewModel extends ViewModel {
    private DocumentReference uidRef;

    @Inject
    UserViewModel(DocumentReference uidRef) {
        this.uidRef= uidRef;
        //Use uidRef
    }
}

【问题讨论】:

标签: android dependency-injection google-cloud-firestore dagger-2 dagger


【解决方案1】:

您在尝试注入依赖项时具有正确的心态,但不幸的是,并非所有依赖项都可以通过constructor injection 提供,其中一些需要一些仅在运行时才知道的信息。

查看您的代码,UserViewModel 被注入到 MainActivity 中,它的一些依赖项是通过构造函数注入提供的,但您必须通过 setter injection 行中的 setter injection 提供其 uid 依赖项,一旦uid 在运行时检索。

一旦知道 uid,您的代码在从列表中检索 DocumentReference 时似乎很好。也许更改 MainActivity 中的代码以检索 DocumentReference 并通过 setter 将其提供给 UserViewModel?

    String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
    userViewModel.setDocumentReference(db.collection("users").document(uid));

如果您真的想像您描述的那样将 DocumentReference 直接注入到您的视图模型类中,您可以将 uid 作为构造函数参数添加到您的 AppModule。

但假设您的 AppModule 由在您的 Application 类中创建的 AppComponent 使用,您将没有 Application 类中的 uid 来创建 AppModule。

因此,您必须为您的 UserViewModel 类创建另一个组件,例如 UserComponent。并创建一个 UserModule,它在构造函数中接收 uid 作为参数。

然后在您的 MainActivity 中,一旦您检索到 uid,您就可以创建 UserComponent:

    UserComponent userComponent = DaggerUserComponent.builder().userModule(new UserModule(uid)).build();
    userViewModel.setUserComponent(userComponent);

这就是你的 UserViewModel 的样子:

public class UserViewModel extends ViewModel {
    @Inject    
    private DocumentReference uidRef;


    public void setUserComponent(UserComponent userComponent) {
        userComponent.inject(this);
    }
}

【讨论】:

  • 感谢您的回答古斯塔沃。所以你说我可以在UserViewModel 类中使用uidRef,因为它是通过userComponent.inject(this); 注入的?
  • 是的,在调用 userComponent.inject 时会注入 DocumentReference,因为 UserModule 有 DocumentReference 的提供者方法
  • @Jorn 你能给出一个完整的解决方案吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多