[英]What is the difference between empty constructor module and a module which provides dependency with a parameter in Dagger 2?
I am trying to learn DI with Dagger 2 by implementing it in a small example. 我正在尝试通过一个小示例通过Dagger 2学习DI。 I got the concept of @Module and @Component. 我有@Module和@Component的概念。 @Component binds @Module with the class where dependencies need to be injected. @Component将@Module与需要注入依赖项的类绑定。
Dagger generates Dagger and it has a Builder class which provides and initializes dependencies. Dagger生成Dagger,并且具有提供并初始化依赖项的Builder类。
So I was trying out some scenarios for better understanding of Dagger 2. I have some questions but I will go with one right now. 因此,我正在尝试一些场景以更好地理解Dagger2。我有一些问题,但是我现在将继续讨论。
I need to inject DatabaseHelper class. 我需要注入DatabaseHelper类。 I created DatabaseModule class for that. 我为此创建了DatabaseModule类。 I also found out that I could skip that class and add a method in my main ApplicationModule to provide DatabaseHelper. 我还发现我可以跳过该类,并在主ApplicationModule中添加一个方法来提供DatabaseHelper。 To do that I must not add DatabaseModule to ApplicationComponent modules list. 为此,我一定不要将DatabaseModule添加到ApplicationComponent模块列表中。 Anyway, I have kept DatabaseModule in ApplicationComponent modules list and remove the method from ApplicationModule. 无论如何,我将DatabaseModule保留在ApplicationComponent模块列表中,并从ApplicationModule中删除了该方法。 Coming back to my question. 回到我的问题。
I have two options when it comes to creating DatabaseModule class. 关于创建DatabaseModule类,我有两个选择。 Here's the first one. 这是第一个。
@Module
public class DatabaseModule {
private Application app;
public DatabaseModule(Application app) {
this.app = app;
}
@Singleton
@Provides
public DatabaseHelper provideDBHelper() {
return new DatabaseHelper(app.getApplicationContext());
}
}
And the second option is, 第二种选择是
@Module
public class DatabaseModule {
@Singleton
@Provides
public DatabaseHelper provideDBHelper(Application app) {
return new DatabaseHelper(app.getApplicationContext());
}
}
If I use the second method, I need not call Component Builder's method .databaseModule()
as Dagger takes care of it. 如果使用第二种方法,则无需调用Component Builder的.databaseModule()
方法,因为Dagger会处理它。 And this is quite insignificant, I guess. 我猜这并不重要。
My question is - What is the difference between these two? 我的问题是-两者之间有什么区别? Which one should I use? 我应该使用哪一个? what are the pros and cons of each method. 每种方法的优缺点是什么。 Also, if I want to inject DatabaseHelper in a class where Application is not accessible, can I do it with the first choice? 另外,如果我想在无法访问Application的类中注入DatabaseHelper,我可以选择第一类吗? (As it is providing a singleton). (因为它提供了一个单例)。
Please point out if I am doing something wrong and need to change to something else. 请指出我做错了什么,是否需要更改为其他内容。 Here's my ApplicationModule and ApplicationComponent classes. 这是我的ApplicationModule和ApplicationComponent类。
@Module
public class ApplicationModule {
private Application mApplication;
public ApplicationModule(Application app) {
mApplication = app;
}
@Singleton
@Provides
Application provideApplication() {
return mApplication;
}
}
ApplicationComponent class ApplicationComponent类
@Singleton
@Component(
modules = {
ApplicationModule.class,
DatabaseModule.class
}
)
public interface ApplicationComponent {
Application getApplication();
void inject(MyApplication app);
DatabaseHelper getDBHelper();
}
This will sound pretty odd, but the difference between a @Module
that receives a parameter in its constructor and a @Module
that doesn't receive a parameter in its constructor is that one of them receives a parameter and the other one doesn't. 这听起来很奇怪,但是在其构造函数中接收参数的@Module
和在其构造函数中不接收参数的@Module
之间的@Module
是,其中一个接收参数,而另一个不接收参数。
Yes, it's quite tautological, I know. 是的,我很讲重言。 You should provide the constructor parameter if it's necessary for the module to function with it (for example, if you need a context, you'll probably want to provide the application/activity to the module for its given scope). 如果模块需要与之一起使用,则应提供构造函数参数(例如,如果需要上下文,则可能需要为模块提供给定范围的应用程序/活动)。 If it doesn't need an external parameter, then there's no point in giving it one. 如果不需要外部参数,则没有必要为其提供任何参数。
The key difference is that modules with external parameters must be explicitly given to the Dagger___Component.builder()
method on construction. 关键区别在于,必须在构造时将具有外部参数的模块显式赋予Dagger___Component.builder()
方法。 If all of your modules are unparametrized, then you can use the Dagger___Component.create()
method instead, which creates every non-parametrized modules for you. 如果所有模块均未参数化,则可以改用Dagger___Component.create()
方法,该方法将为您创建每个未参数化的模块。
If you want to make an ApplicationModule
without parameter, then you'd probably have to do something like this 如果要创建不带参数的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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.