ModuleAをアプリケーション全体のシングルトンプロバイダーとしてセットアップし、ModuleBをユーザー関連のオブジェクトプロバイダーとしてセットアップしました
私のユーザー表示フラグメントは、システム全体のバスを使用して他のユーザーにメッセージを送信し、ユーザー関連のオブジェクトを使用して表示します。
問題は、異なるscropeクラスを1つのオブジェクトに挿入できません。 component.getXメソッドを使用すると正常に機能しますが、注入することをお勧めします。エラーメッセージ:@ UserScopeはスコープが異なるバインディングを参照できない可能性があります:@Provides @Singleton Bus ModuleA.provideBus()
@Module
public class ModuleA {
@Provides @Singleton Bus provideBus() {...}
}
ユーザー関連の情報プロバイダーとしてのモジュールB
@Module
public class ModuleB{
private final User user;
public ModuleB(User user) {...}
@Provides @UserScope User provideUser() {}
@Provides @UserScope UserManager provideUserManager() {}
}
次のようなコンポーネントのセットアップ:
@Component (modules={ModuleA.class})
@Singleton
public interface ComponentA {
Bus getBus();
void inject(ClassA target);
}
@Component(modules={ModuleB.class})
@UserScope
public interface ComponentB {
User getUser();
UserManager getUserManager();
void inject(ClassA target);
}
class UserFragment exrtends Fragment {
@Inject Bus bus;
@Inject UserManager userManager;
public void onCreate() {
getComponentA().inject(this);
getComponentB().inject(this);
}
}
この構成を試してください、それは私のために働きます。 Dagger2に関する優れたドキュメントが本当に不足しているため、GitHubなどでDagger2のようなキーワードで見つけることができるコードのオープンソースの例をいくつか調べました。
アプリケーションレベルのコンポーネント
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
// exported for child-components
Bus eventBus();
}
アプリケーションレベルのモジュール
@Module
public class AppModule {
@Provides @Singleton
Bus provideBus() {
return BusProvider.getInstance();
}
}
アクティビティレベルコンポーネント
@ActivityScope
@Component(dependencies=AppComponent.class, modules=MainActivityModule.class)
public interface MainActivityComponent {
void inject( MainActivity mainActivity );
}
アクティビティレベルモジュール
@Module
public class MainActivityModule {
private final MainActivity mActivity;
public MainActivityModule( MainActivity activity ) {
mActivity = activity;
}
@Provides
MainActivityTitleController provideTitleController() {
return new MainActivityTitleController( mActivity );
}
}
Androidアプリケーションクラス
public class MyApplication extends Application {
private AppComponent mAppComponent;
@Override
public void onCreate() {
super.onCreate();
// Dagger2
mAppComponent = Dagger_AppComponent.builder()
.appModule( new AppModule( this ))
.build();
}
public AppComponent getComponent() {
return mAppComponent;
}
public static AppComponent getComponent( Context context ) {
return ((MyApplication)context.getApplicationContext()).getComponent();
}
}
そして最後にアクティビティ
public class MainActivity extends ActionBarActivity {
// Injectable fields
@Inject Bus mEventBus;
@Inject MainActivityTitleController mTitleController;
private MainActivityComponent mComponent;
@Override
protected void onCreate( Bundle savedInstanceState ) {
// Dagger2
mComponent = Dagger_MainActivityComponent.builder()
.appComponent( ((MyApplication)getApplication()).getComponent() )
.mainActivityModule( new MainActivityModule( this ) )
.build();
mComponent.inject( this );
}
}
提供したコードスニペットの主な問題は、取得したエラーをシングルトンに正しく提供するために、ModuleB
がModuleA
に依存している必要があることだと思います。つまりこれはうまくいくはずです:
@Component(modules={ModuleB.class}, dependencies = ComponentA.class)
@UserScope
public interface ComponentB {
User getUser();
UserManager getUserManager();
void inject(MainActivity target);
}
私はあなたのクラスを再作成し、空白を埋めるためにいくつかの仮定をしました、そしてそれはうまくいくようです。完全に機能するコードを見ることができます ここではGitHub 。私のコードの唯一の違いは、あなたがClassA
/UserFragment
と呼んだものです。私はMainActivity
と呼んだだけですが、それ以外は構造は同じです。