依赖 gradle 用于共享代码的库模块时如何使用 dagger?

How to use dagger when depending on gradle library module used to share code?

我正在将一个项目切换到 dagger。 项目由:app gradle模块和:library gradle模块组成。库在某种意义上不是真正的库,而是一种共享代码的方式。应用程序的变体。

所以基本上它提供了例如 BaseFooFragment 由 :app 模块通过 FooFragment 扩展。 更具体的例子是 BaseRestManager,它在整个库中使用。 App 应该将其扩展到 RestManager。也应该是单例。

如果没有 dagger,我通常会做的是让 BaseApp 应用程序 class 在 :library 模块中提供 BaseRestManager 并在库中使用它。在应用程序模块中,我会将 BaseApp 子class 到 App 并覆盖 BaseRestManager ,提供 RestClient 并将 return 类型从 BaseRestManager getRestManager 缩小到 RestManager getRestManager,因此也不必强制转换应用程序代码。

顺便说一句,库模块将永远是模块,它不需要它自己工作。它只是一种共享代码的方式。干

我如何在匕首中做到这一点?如果我有一个@Provides 方法returning BaseRestManager 和第二个@Provides returning RestManager 都注释了@Singleton,它显然会创建2 个实例,这不是我想要的。它应该只有一个,RestManager 的实例。

public abstract class BaseApp extends Application {
    public abstract BaseRestManager getRestManager();
}

public class App extends BaseApp {

    private RestManager mRestManager;

    @Override
    public void onCreate() {
        super.onCreate();
        mRestManager = new RestManager(...);
    }

    @Override public RestManager getRestManager() {
        return mRestManager;
    }
}

public class BaseFooFragment extends Fragment {

    @Override public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("Default", "BaseFooFragment # baseRestManager=" + ((BaseApp) getActivity().getApplication()).getRestManager());
    }
}

public class FooFragment extends BaseFooFragment {

    @Override public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("Default", "FooFragment # restManager=" + ((App) getActivity().getApplication()).getRestManager());
    }
}

日志语句应该打印相同的 RestManager 实例。在 dagger id 中,代码可能看起来像这样

public class BaseFooFragment extends Fragment {

    @Inject BaseRestManager mBaseRestManager;

    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((BaseApp) getActivity().getApplication()).getComponent().inject(this);
    }
}

public class FooFragment extends Fragment {

    @Inject RestManager mRestManager;

    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((App) getActivity().getApplication()).getComponent().inject(this);
    }
}

有什么建议吗?谢谢

你可以在 Dagger 中提供一个接口的多个子类。 喜欢这个:

FirebaseDataRepository 实现 DataRepository

@Singleton
@Provides
@Named(Scope.FIREBASE)
public DataRepository provideFirebaseData(FirebaseDataRepository repo) {
    return repo;
}

您还可以提供另一个 AnyDataReposity 实现 DataRepository

P/s: 注入时必须指定要使用哪个:

@Named(Scope.FIREBASE) DataRepository dataRepo