如何使用Dagger 2从多个独立组件中为父/子活动注入不同的依赖项?

时间:2016-03-07 04:08:31

标签: java android dependency-injection dagger-2

我对Dagger 2比较陌生,而且我一直遇到来自Dagger 2的编译器错误,说缺少@Provide@Produces。我想要做的是在基类中注入通用组件,然后子类也有自己的组件。我在网上看了几个例子,看到人们使用子组件;但我仍然不明白为什么我们可以为每个班级提供多个独立的组件?我不明白为什么我的ImageComponent必须是ApiComponent的子组件,它只是没有任何意义。所以我想知道关于这个问题的正确方法是什么,或者是否有任何我不知道的替代方法?谢谢。

Api Component

public interface UserApi {

    int getUser();
}

public interface SearchApi {

    int search();
}

@Singleton
@Module
public class ApiModule {

    public ApiModule() {
    }

    @Singleton
    @Provides
    public SearchApi provideSearchApi() {
        return new SearchApi() {
            @Override
            public int search() {
                return 0;
            }
        };
    }

    @Singleton
    @Provides
    public UserApi provideUserApi() {
        return new UserApi() {
            @Override
            public int getUser() {
                return 0;
            }
        };
    }
}

@Singleton
@Component(modules = {
    ApiModule.class
})
public interface ApiComponent {

    void inject(BaseActivity activity);
}

Image Component

public interface ImageLoader {

    boolean load(String url);
}

@ActivityScope
@Module
public class ImageModule {

    @ActivityScope
    @Provides
    public ImageLoader provideImageResource() {
        return new ImageLoader() {
            @Override
            public boolean load(String url) {
                return false;
            }
        };
    }
}

@ActivityScope
@Component(
    modules = {
        ImageModule.class
    }
)
public interface ImageComponent {
    // Dagger doesn't allow this? Not sure why?
    void inject(MainActivity activity);
}

Activity and Components Singleton

public class Components {

    private ApiComponent apiComponent;

    private ImageComponent imageComponent;

    private static Components singleton;

    public static void initialize(Context context) {
        if (singleton != null) {
            throw new RuntimeException("Attempted to initialize components twice");
        }
        singleton = new Components(context);
    }

    public static Components get() {
        return singleton;
    }

    private Components(Context context) {
        apiComponent = ApiComponent
            .builder()
            .dataModule(new ApiModule())
            .build();

        // Can't generate image component yet
    }

    public ApiComponent api() {
        return apiComponent;
    }

    public ImageComponent image() {
        return imageComponent;
    }
}
public abstract class BaseActivity extends AppCompatActivity {

    @Inject
    protected UserApi userApi;

    @Inject
    protected SearchApi searchApi;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Components.get().data().inject(this);
    }
}

public class MainActivity extends BaseActivity {

    @Inject
    protected ImageLoader imageLoader;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

stacktrace

Error:(15, 10) error: android.com.dagger.data.UserApi cannot be provided without an @Provides- or @Produces-annotated method.
android.com.dagger.BaseActivity.userApi
[injected field of type: android.com.dagger.data.UserApi userApi]

1 个答案:

答案 0 :(得分:3)

基类不足以作为注射目标。 Dagger 2依赖于强类型类,因此必须明确指定应定义哪些类

你不能这样做Components.get().data().inject(this); this(即BaseActivity是抽象的)