web-dev-qa-db-ja.com

ダガー2:他のスコープにシングルトンを注入できません

アプリケーション、DBサービスなど、いくつかの標準シングルトンを提供するシングルトンスコープモジュールがあります。ただし、アクティビティの場合、アクティビティのプレゼンターを作成する別のモジュールがあり、アプリケーションコンテキストを渡す必要があります。ただし、プロジェクトをコンパイルしようとすると、次のエラーが発生します。

Error:(13, 1) error: xxx.SplashComponent scoped with @xxx.ViewScope may not reference bindings with different scopes:
@Provides @Singleton xxx.ApplicationModule.provideAppContext()

これが私のアプリケーションモジュールのスニペットです:

@Singleton
@Module
public class ApplicationModule {

    private Application app;

    public ApplicationModule(Application app) {
        this.app = app;
    }

    @Provides
    @Singleton
    @Named("ui")
    Scheduler provideUIScheduler() {
        return AndroidSchedulers.mainThread();
    }

    @Provides
    @Singleton
    @Named("io")
    Scheduler provideIOScheduler() {
        return Schedulers.io();
    }

    @Provides
    @Singleton
    Application provideApplication() {
        return app;
    }

    @Provides
    @Singleton
    Context provideAppContext() {
        return app;
    }
}

そして、これがアクティビティモジュールとコンポーネントです。

@Module
public class SplashModule {
    private final FragmentManager fragmentManager;

    public SplashModule(FragmentManager fragmentManager) {

        this.fragmentManager = fragmentManager;
    }

    @Provides
    @ViewScope
    Presenter getPresenter(Context context) {
        return new SplashPresenter(context, fragmentManager);
    }
}

成分:

@ViewScope
@Component(modules = {SplashModule.class, ApplicationModule.class})
public interface SplashComponent {
    void inject(SplashActivity activity);
}

私は何が間違っているのですか?

11
Heisenberg

私は何が間違っているのですか?

この:

@ViewScope
@Component(modules = {SplashModule.class /*View scoped*/,
    ApplicationModule.class/*Singleton scoped*/})

コンポーネントには、スコープなしまたはスコープがsameスコープのモジュールのみを含めることができます。複数のコンポーネントを使用する必要があります。

アプリケーションからの依存関係を含めるには、それらを別のコンポーネントに含める必要があります。 ApplicationComponent。これを行う場合、2つのオプションがあります。SplashComponentSubComponentApplicationComponentとして宣言するか、コンポーネントへの依存関係としてApplicationComponentを追加します。依存関係として追加する場合は、依存関係にアクセスできるように、必ずApplicationComponentにもメソッドを指定してください。

例えばコンポーネントの依存関係を使用する場合:

@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {

    void inject(MyApplication app);

    // todo: also add getters for your other dependencies you need further down the graph
    Application getApplication();

}

@Component(modules = {SplashModule.class}, dependencies={ApplicationComponent.class})
public interface SplashComponent {
    // as before
}
13
David Medenjak

私の理解から、ダガー2のいくつかの重要なポイントを説明したいと思います。

主演者:

  • 「コンポーネント」は、モジュールと注入が行われる場所の間のブリッジです。

  • 「モジュール」は、注入されるオブジェクトを宣言する場所です。

  • 「スコープ」は、関連する注射ストーリーの寿命のようなものです。

どのように機能しますか?

  • スコープ(「シングルトン」)を使用してコンポーネントを宣言します。
  • コンポーネントのモジュールリストに必要なオブジェクトを挿入できるモジュールを定義します。

void inject(BaseFragment baseFragment);

*******コンポーネントのモジュールで提供されたオブジェクトをサブコンポーネントに公開します****
DbHelper dbHelper();

  • モジュールを宣言し、コンポーネントを介して注入されるオブジェクトを提供します。

例:

@Singleton 
@Component(modules = { ApplicationModule.class, NetworkModule.class })
public interface ApplicationComponent {

  void inject(BaseActivity baseActivity);
  DbHelper dbHelper();
}




@PerService @Component(dependencies = ApplicationComponent.class, modules = ServiceModule.class)
public interface ServiceComponent {

  void inject(SyncService service);

}

// SyncService.Java

  @Inject DbHelper dbHelper;  (even Singleton scoped)

  private void setupInjector() {
    ServiceComponent mServiceComponent = DaggerServiceComponent.builder()
        .applicationComponent(getApplicationComponent())
        .serviceModule(new ServiceModule(this))
        .build();
    mServiceComponent.inject(this);
  }

わかりました... enter image description here

スコープなしオブジェクトと(シングルトンおよびPerService)スコープ付きオブジェクトの両方をSyncService.classに挿入できます。

11
huseyin

スコープルール:

  • タイプがスコープ注釈でマークされている場合、同じスコープで注釈が付けられているコンポーネントでのみ使用できます。
  • コンポーネントがスコープアノテーションでマークされている場合、そのアノテーションのあるタイプまたはアノテーションのないタイプのみを提供できます。
  • サブコンポーネントは、その親コン​​ポーネントの1つで使用されるスコープ注釈を使用できません。

このコンテキストでは、コンポーネントにはサブコンポーネントも含まれます。

注意:-スコープ注釈を使用するモジュールは、同じスコープで注釈が付けられたコンポーネントでのみ使用できます。ここをチェック

Daggerの詳細については、Androidを通過 このトレーニング そして練習 ここにあります

0