Как использовать dagger в проекте библиотеки android

в настоящее время я пытаюсь добавить Dagger в свои проекты android. Для проектов приложений его легко и ясно для меня, как построить ObjectGraph. Но я не совсем знаю, что лучший способ сделать это в моих проектах библиотеки android.

должен ли я продолжать строить ObjectGraph в классе приложений приложений и передавать OG в LibraryModule - plussing OG библиотеки в OG приложений? Или я должен построить весь ObjectGraph в библиотеке?

что если мне нужно чтобы ввести класс в библиотеку с помощью ObjectGraph.inject(this)? В моих проектах приложений я могу получить OG из класса Application. Но как справиться с этим в библиотеке? Должен ли я добавить метод @Provides для ObjectGraph?

большое спасибо за вашу помощь.

изменить: Короче говоря: как я могу позвонить ObjectGraph.inject(this) в моем проекте библиотеки, где у меня нет доступа к OG, потому что он строится в классе приложения?

4 ответов


в случае, если кто-то с помощью Dagger 2 получает здесь, это так, как я сделал в моем приложении:

в модуле библиотеки я создал следующий модуль и компонент:

@Module
public class ModuleUtil {

    @Provides
    public RestTemplate provideRestTemplate() {
        return new RestTemplate();
    }

}

@Singleton
@Component(
        modules = {
                ModuleUtil.class
        })
public interface MainComponent {
    void inject(Postman postman);
}

и затем я создал Синглтон ниже, чтобы управлять инъекциями:

public class DaggerWrapper {

    private static MainComponent mComponent;

    public static MainComponent getComponent() {
        if (mComponent == null) {
            initComponent();
        }
        return mComponent;
    }

    private static void initComponent () {
       mComponent = DaggerMainComponent
                .builder()
                .utilModule(new ModuleUtil())
                .build();
    }
}

когда какой-то класс из библиотечного модуля должен ввести свои члены, я просто вызываю DaggerWrapper.getComponent().inject(this); и это не он.


Я делаю так:

  1. @Module классы принадлежат к основному проекту, и они предоставляют реализации, которые вы вводите в элементы библиотеки, поэтому в проектах библиотеки нет классов @Module

  2. элементы библиотеки, которые ожидают зависимости, должны иметь доступ к ObjectGraph и вызову .inject() на себя, но основной проект должен дать экземпляр ObjectGraph библиотеке с предоставленным @Module зависимость

  3. как получить ObjectGraph из основного проекта в библиотеку? У вас может быть такой интерфейс:

    interface Injector {
        void inject(Object object);
        public ObjectGraph getObjectGraph(); 
    }

объекты контекста, такие как Activity или Application class, реализуют этот интерфейс (держатели объектов ObjectGraph).

Если у вас есть пример активности в модуле библиотеки, который нужно что-то ввести из основного проекта, это будет выглядеть так:

class LibraryActivity extends Activity {

    @Inject ActivationModule instance;

    void onCreate(... ) {
        Injector injector = (Injector)getApplicationContext();
        injector.inject(this)
    }
}

ActivationModule является класс / интерфейс в проекте библиотеки.

основной проект имеет класс приложения, который реализует интерфейс инжектора и создает ObjectGraph с предоставленным dependecy для ActivationModule в проекте библиотеки.

class MyApplicationInTheMainProject extends Application implements Injector {

    ObjectGraph graph;

    @Override
    public void onCreate() {
        super.onCreate();
        graph = ObjectGraph.create(new ActivationModuleImpl(this));
    }

    @Override public void inject(Object object) {
        graph.inject(object);
    }

    @Override public ObjectGraph getObjectGraph() {
        return graph;
    }
}


@Module(injects = {
        LibraryActivity.class
}, library = true)
class ActivationModuleImpl implements ActivationModule {
    ....
}

Если вы даете эту библиотеку людям, и они ничего не знают о вашем сценарии, поэтому вы должны написать его таким образом, чтобы ваш Кинжал работал отлично без какой-либо помощи пользователя. (легче работать с лучшей практикой)

Я просто написал какую-то библиотеку для вас, чтобы показать, как это делать. я написал библиотеку таким образом, что вы даже можете запустить ее автономно и увидеть результат на вкладке "Сообщения". пользователь вашей библиотеки не должен ничего знать о dagger и ничего не делает просто использует библиотеку и Кинжал будет настроен:

https://github.com/amirziaratii/libraryUsingDagger.git

Если эта библиотека-это то, что вы используете ее сами и для своего собственного проекта, Лучшая практика-сделать это, как в этом проекте моего друга:

https://github.com/mmirhoseini/trakt.tv

на все ваши вопросы отвечают в этих двух проектах. задайте любой вопрос и я отвечу в комментариях.


вот полный пример того, как использовать кинжал в приложении Шаг 1 добавьте depedancy к уровню проекта gradle из classpath 'com по.нинбеданкт.градля.Плагины: android-apt:1.8' Шаг 2 модуль уровня depedancy

применить плагин: 'com.андроид.применение применить плагин: 'android-apt' применить плагин: 'ком.нинбеданкт.android-apt'

compile 'com.google.dagger:dagger:2.0'
provided 'com.google.dagger:dagger-compiler:2.0'
provided 'org.glassfish:javax.annotation:10.0-b28'

Шаг 3 построить Кинжал с вашим классом приложения

public class TubeMateApp расширяет приложение {

public  AppComponent component;
public static TubeMateApp singleton;


public static TubeMateApp getInstance() {
    return singleton;
}

@Override
public void onCreate() {
    super.onCreate();
    singleton = this;
    setupGraph();
}

private void setupGraph() {
    component = DaggerAppComponent.builder()
            .appModule(new AppModule(this))
            .build();

    component.inject(this);
}


public AppComponent component() {
    return component;
}

} Шаг 4 Создайте модуль такой

модуль@ открытый класс модуль {

private TubeMateApp app;

public AppModule(TubeMateApp application) {
    this.app = application;
}



@Provides
public Application provideApplication() {
    return app;
}

@Provides
@Singleton
Prefs prefs(){
    return Prefs.with(app);
}

// To use your custom requirement code here for example i have used Picasso with in the application

@Provides
@Singleton
Picasso getPicasso(){
    return Picasso.with(app);
}

@Provides
@Singleton
LayoutInflater getLayoutInflater() {
    return (LayoutInflater) app.getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

} Шаг 5 Создайте компоненты приложения, которые необходимо ввести компоненты приложения dagger здесь Шаг 6 Используйте кинжал в основной всплеск активности как применить Кинжал инъекции см Этот скриншот