Как использовать dagger, когда в зависимости от модуля библиотеки gradle, используемого для совместного использования кода?

Переключаю проект на кинжал. Проект состоит из: модуля gradle приложения и модуля: библиотеки gradle. Библиотека - это не настоящая библиотека в определенном смысле, а способ совместного использования общего кода кода между вариантами приложения.

Таким образом, в основном он предоставляет, например, BaseFooFragment, который может быть расширен: модулем приложения через FooFragment. Более конкретным примером будет BaseRestManager, который используется во всей библиотеке. Приложение должно расширить его до RestManager. Также это должен быть синглтон.

То, что я обычно делал бы без кинжала, - это иметь класс приложения BaseApp в модуле: library, обеспечить BaseRestManager и использовать его внутри библиотеки. В модуле приложения я бы подклассифицировал BaseApp в App и переопределил BaseRestManager, предоставил RestClient и сузил возвращаемый тип от BaseRestManager getRestManager до RestManager getRestManager, поэтому также использование кода приложения не должно его преобразовывать.

Модуль библиотеки Btw всегда будет модулем, его не нужно, чтобы он работал сам по себе. Это просто способ поделиться кодом. СУХОЙ.

Как мне сделать это в кинжале? Если у меня есть метод @Provides, возвращающий BaseRestManager, а второй @Provides, возвращающий 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. В идентификаторе кинжала код может выглядеть так

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);
    }
}

Какие-нибудь советы? Спасибо


person urSus    schedule 21.11.2017    source источник


Ответы (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
person Son Tieu    schedule 21.11.2017