Dagger v2:将2个不同的范围注入一个对象

时间:2015-03-13 16:53:25

标签: android dagger-2

我将moduleA设置为应用程序范围的单例提供程序,ModuleB作为用户相关的对象提供程序

我的用户显示片段将使用系统总线向他人发送消息并使用用户相关对象进行显示。

问题不能将不同的scrope类注入一个对象。使用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);
   }
}

2 个答案:

答案 0 :(得分:23)

试试这个配置,它对我有用。实际上缺乏关于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 );
    }
}

答案 1 :(得分:9)

我认为您提供的代码段中的主要问题是,ModuleB应该依赖ModuleA来正确地为单身人士提供您所获得的错误。即这应该有效:

@Component(modules={ModuleB.class}, dependencies = ComponentA.class)
@UserScope
public interface ComponentB {
    User getUser();
    UserManager getUserManager();
    void inject(MainActivity target);
}

我重新创建了你的类并做了一些假设来填补空白,它似乎工作得很好。您可以看到完整的工作代码here on GitHub。我的代码中唯一的区别是,您所谓的ClassA / UserFragment我刚刚调用MainActivity,但结构是相同的。