В чем разница между пустым модулем конструктора и модулем, который обеспечивает зависимость от параметра в Dagger 2?

Я пытаюсь изучить DI с помощью Dagger 2, реализовав его в небольшом примере. У меня появилась концепция @Module и @Component. @Component связывает @Module с классом, в который нужно внедрить зависимости.

Dagger генерирует Dagger, и у него есть класс Builder, который предоставляет и инициализирует зависимости.

Итак, я пробовал несколько сценариев для лучшего понимания Dagger 2. У меня есть несколько вопросов, но я отвечу на один прямо сейчас.

Мне нужно ввести класс DatabaseHelper. Для этого я создал класс DatabaseModule. Я также обнаружил, что могу пропустить этот класс и добавить метод в свой основной ApplicationModule для предоставления DatabaseHelper. Для этого я не должен добавлять DatabaseModule в список модулей ApplicationComponent. В любом случае, я сохранил DatabaseModule в списке модулей ApplicationComponent и удалил метод из ApplicationModule. Возвращаясь к моему вопросу.

У меня есть два варианта создания класса DatabaseModule. Вот первый.

@Module
public class DatabaseModule {

    private Application app;

    public DatabaseModule(Application app) {
        this.app = app;
    }

    @Singleton
    @Provides
    public DatabaseHelper provideDBHelper() {
        return new DatabaseHelper(app.getApplicationContext());
    }
}

И второй вариант:

@Module
public class DatabaseModule {

    @Singleton
    @Provides
    public DatabaseHelper provideDBHelper(Application app) {
        return new DatabaseHelper(app.getApplicationContext());
    }
}

Если я использую второй метод, мне не нужно вызывать метод Component Builder .databaseModule(), поскольку Dagger позаботится об этом. И это, я думаю, совсем несущественно.

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

Укажите, пожалуйста, если я делаю что-то не так и мне нужно что-то изменить. Вот мои классы ApplicationModule и ApplicationComponent.

@Module
public class ApplicationModule {
    private Application mApplication;

    public ApplicationModule(Application app) {
        mApplication = app;
    }

    @Singleton
    @Provides
    Application provideApplication() {
        return mApplication;
    }
}

ApplicationComponent класс

@Singleton
@Component(
        modules = {
            ApplicationModule.class,
            DatabaseModule.class
        }
)
public interface ApplicationComponent {
    Application getApplication();
    void inject(MyApplication app);
    DatabaseHelper getDBHelper();
}

person Froyo    schedule 29.08.2015    source источник


Ответы (1)


Это будет звучать довольно странно, но разница между @Module, который получает параметр в своем конструкторе, и @Module, который не получает параметр в своем конструкторе, заключается в том, что один из них получает параметр, а другой - нет.

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

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

Если вы хотите сделать ApplicationModule без параметра, вам, вероятно, придется сделать что-то вроде этого

public enum ApplicationHolder {
    INSTANCE;

    private CustomApplication customApplication;

    void setApplication(CustomApplication customApplication) {
        this.customApplication = customApplication;
    }

    public CustomApplication getApplication() {
        return application;
    }
}

public class CustomApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ApplicationHolder.INSTANCE.setApplication(this);
    }
}

@Module
public class ApplicationModule {
    @Provides
    public CustomApplication customApplication() {
        return ApplicationHolder.INSTANCE.getApplication();
    } 
}
person EpicPandaForce    schedule 29.08.2015