11

我将 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);
   }
}
4

2 回答 2

24

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

安卓应用类

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 );
    }
}
于 2015-03-15T18:35:47.020 回答
9

我认为您提供的代码片段中的主要问题是您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但结构是一样的。

于 2015-07-30T00:28:17.860 回答