Java 空构造函数模块和在Dagger 2中使用参数提供依赖关系的模块之间有什么区别?

Java 空构造函数模块和在Dagger 2中使用参数提供依赖关系的模块之间有什么区别?,java,android,dependency-injection,dagger-2,Java,Android,Dependency Injection,Dagger 2,我试图通过在一个小示例中实现Dagger2来学习DI。我明白了 @模块和@组件@组件将@Module与需要注入依赖项的类绑定 Dagger生成Dagger,它有一个提供和初始化的生成器类 依赖关系 所以我尝试了一些场景来更好地理解匕首2。我有一些问题,但我会去的 现在有一个 我需要注入DatabaseHelper类。我为此创建了DatabaseModule类。我还发现 我可以跳过这个类,在主ApplicationModule中添加一个方法来提供DatabaseHelper。做 我不能将Datab

我试图通过在一个小示例中实现Dagger2来学习DI。我明白了 @模块和@组件@组件将@Module与需要注入依赖项的类绑定

Dagger生成Dagger,它有一个提供和初始化的生成器类 依赖关系

所以我尝试了一些场景来更好地理解匕首2。我有一些问题,但我会去的 现在有一个

我需要注入DatabaseHelper类。我为此创建了DatabaseModule类。我还发现 我可以跳过这个类,在主ApplicationModule中添加一个方法来提供DatabaseHelper。做 我不能将DatabaseModule添加到ApplicationComponent模块列表中。无论如何,我保留了数据库模块 在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();
}

这听起来很奇怪,但在构造函数中接收参数的
@Module
和在构造函数中不接收参数的
@Module
之间的区别在于,其中一个模块接收参数,而另一个模块不接收参数

是的,我知道这是很重复的。如果模块需要使用构造函数参数运行,则应提供构造函数参数(例如,如果需要上下文,则可能需要为模块提供给定范围的应用程序/活动)。如果它不需要外部参数,那么给它一个也没有意义

关键区别在于,具有外部参数的模块必须在构造时显式地指定给
Dagger\uuu Component.builder()
方法。如果所有模块都未参数化,则可以使用
Dagger\uuuu组件.create()
方法,该方法将为您创建所有未参数化的模块

如果您想创建一个不带参数的
应用程序模块
,那么您可能必须这样做

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