【问题标题】:How to use dagger when depending on gradle library module used to share code?依赖用于共享代码的gradle库模块时如何使用匕首?
【发布时间】:2017-11-21 05:14:08
【问题描述】:

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

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

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

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

我将如何在匕首中做到这一点?如果我有一个返回 BaseRestManager 的 @Provides 方法和返回 RestManager 的第二个 @Provides 方法都注释了 @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);
    }
}

有什么建议吗?谢谢

【问题讨论】:

    标签: java android dagger-2 dagger


    【解决方案1】:

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

    FirebaseDataRepository 实现 DataRepository

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

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

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

    @Named(Scope.FIREBASE) DataRepository dataRepo
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-23
      相关资源
      最近更新 更多