簡體   English   中英

了解Dagger2子組件

[英]Understanding Dagger2 subcomponents

我的應用程序中包含以下Dagger2體系結構:

-- AppComponent (@PerApplication)
  -- UserComponent (@PerUser)
    -- ActivityComponent (@PerActivity)
      -- ChatComponent (@PerActivity) <-- 1

其中:AppComponent:

@PerApplication
@Component(modules = {ApplicationModule.class, StorageModule.class, NetworkModule.class})
public interface ApplicationComponent {
    UserComponent plus(UserModule userComponent);

    //Exposed to sub-graphs.
    Context application();
}

UserComponent:

@PerUser
@Subcomponent(modules = {UserModule.class, RosterModule.class})
public interface UserComponent {
    ActivityComponent plus(ActivityModule activityModule);

    User getMe();

    UserRepository userRepository();
}

ActivityComponent:

@PerActivity
@Subcomponent(modules = ActivityModule.class)
public interface ActivityComponent {

    ChatComponent plus(ChatModule chatComponent);

    //Exposed to sub-graphs.
    Context context();
}

ChatComponent:

@PerActivity
@Subcomponent(modules = {ChatModule.class})
public interface ChatComponent {
    void inject(ChatListFragment chatListFragment);
    void inject(ConversationFragment conversationFragment);
    void inject(NewConversationFragment newConversationFragment);
    void inject(CloudFilesFragment cloudFilesFragment);
    void inject(ChatActivity chatActivity);
    void inject(ConversationActivity conversationActivity);
    void inject(NewConversationActivity newConversationActivity);

    void inject(NewGroupActivity newGroupActivity);
    void inject(NewGroupFragment newGroupFragment);
}

我面臨2個問題:

首先,如何為課程注入不同的Context 應用程序或活動?

其次,在嘗試編譯我的代碼時,我面臨一個奇怪的問題,錯誤是:

錯誤:(23,10)錯誤:如果沒有@Provides注釋的方法,則無法提供br.com.animaeducacao.ulife.domain.interactor.UseCase。 br.com.animaeducacao.ulife.presentation.view.fragment.ChatListFragment.chatListPresenter [類型的插入字段:br.com.animaeducacao.ulife.presentation.presenter.ChatListPresenter chatListPresenter] br.com.animaeducacao.ulife.presentation.presenter ChatListPresenter。(br.com.animaeducacao.ulife.domain.interactor.UseCase chatDialogsUseCase,br.com.animaeducacao.ulife.domain.interactor.UseCase advisorUserPresence,android.content.Context context)[參數:@ javax.inject.Named( “ getChatDialogs”)br.com.animaeducacao.ulife.domain.interactor.UseCase chatDialogsUseCase]

我的ChatListFragment是:

@PerActivity
public class ChatListFragment extends BaseFragment implements ChatListView {

    @Inject
    ChatListPresenter chatListPresenter;
  ...
//called onActivityCreated()
private void initialize() {
        this.getComponent(ChatComponent.class).inject(this);
}

BaseFragment:

protected <C> C getComponent(Class<C> componentType) {
    return componentType.cast(((HasComponent<C>)getActivity()).getComponent());
  }

ChatListPresenter:

@PerActivity
public class ChatListPresenter implements Presenter {

    private final UseCase chatDialogsUseCase;
    private final UseCase adviceUserPresence;
    private final Context context;
    private ChatListView chatListView;

    @Inject
    public ChatListPresenter(@Named("getChatDialogs") UseCase chatDialogsUseCase,
                             @Named("adviceUserPresence") UseCase adviceUserPresence,
                             Context context) {
        this.chatDialogsUseCase = chatDialogsUseCase;
        this.adviceUserPresence = adviceUserPresence;
        this.context = context;
    }

問題是,在我的ChatModule類中,我實現了所有必需的@Provides

@Provides
    @PerActivity
    @Named("getChatDialogs")
    public UseCase provideChatDialogs(@Named("transactionalChatRepository") ChatRepository chatRepository, ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) {
        return new GetUserChatDialogs(chatRepository, threadExecutor, postExecutionThread);
    }

這是一個好方法嗎? 為什么這里不編譯,我在這里缺少什么? 對不起,很長的帖子,謝謝!

嗯,您有多個問題。

1)當你使用正確的subscoping到一個點(你正在 @Subcomponent s請正確地在第一),該ChatComponent實際上並不子范圍其父組件-基本上, ChatComponent不能@PerActivity ,它需要一個第四范圍。

@Subcomponent批注只是一種創建子范圍內的組件的方法,而不必將其指定為組件依賴項。 它仍然需要自己的“更具體”的范圍。

2.)為了使范圍化工作有效,您需要在組件中為該組件要提供的每個依賴項指定配置方法,以便子范圍內的組件可以繼承它們。

例如,您的ApplicationComponent沒有提供StorageModule內容的配置方法,因此StorageModule提供的依賴項不能繼承到子范圍內的組件。

但是,我不確定如果不是在模塊內部,是否可以僅指定要提供的類,而是使用@Inject構造函數對其進行注釋,並用范圍標記該類。

而且,為了允許作用域層次結構A->B->C中的C從A繼承,那么B也需要具有A的提供方法。

因此, UserComponent extends ApplicationComponent是必要的,而ActivityComponent extends UserComponent ,而ChatComponent extends ActivityComponent

3.)您應該使用@Named("application")@Named("activity")批注指定兩個不同的Context ,或者僅在模塊中將它們稱為ApplicationActivity ,以免混淆起來。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM