如何使用在活动中获得的值来注入对象?

时间:2019-09-06 14:22:44

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

我有一个活动,可以从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
    }
}

1 个答案:

答案 0 :(得分:1)

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

看一下代码,将UserViewModel注入到MainActivity中,它的某些依赖关系是通过构造函数注入提供的,但是您必须通过uid提供它的setter injection依赖关系一旦在运行时检索到uid,就在userViewModel.setUid(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);
    }
}