Dagger2 依赖项注入:它在 android 应用程序中如何工作?
Dagger2 dependency injection: How does it work in an android app?
我正在尝试了解 example 一个应用程序,该应用程序具有使用改造和空间的离线支持:
你可以找到它的代码here:
这个项目正在使用 Dagger2 的依赖注入。我从未使用过它,所以我试图了解它们是如何协同工作的。我理解依赖注入的目的,但是我不理解上面项目的实现。
我在这里找到了关于 Dagger2 的非常好的介绍:
A Friendly Introduction to Dagger 2
我完成了它并掌握了大部分内容。回到我试图理解的实际项目 (link 2)。这对我来说仍然没有意义,原因如下:
接口 AppComponent 有一个使用的方法:
public void inject(MainActivity2ViewModel viewModelModule);
return 类型为空。在 Dagger2 示例项目(link 3 和 4)中,他们使用 WeatherReporter getWeatherReporter();
这是有道理的,因为稍后他们调用此方法来获取 WeatherReporter-Instance 并且 Dagger2 在后台管理所有实例化过程。但是如果 return 类型是无效的,我什么也得不到。为什么 return 类型不是对象?
MainActivity2ViewModel中有一个@Inject
:
@注入
public void setRepository(GitHubRepository2 存储库){
this.repository = 存储库;
}
repository
是 MainActivity2ViewModel
的唯一字段,因此它是一个依赖项。 GitHubRepository2
构造函数有 3 个参数:
@Inject
public GitHubRepository2(GitHubApi api, GitHubDao dao, Executor executor)
对于它们中的每一个,都有一个模块解释如何创建这些对象。但是为什么会有 AppModule 和 NetModule 呢?也许 AppModule 在那里是因为 DaoModule 需要一个 Application 引用,但为什么有 NetModule 以及它在哪里使用?
Android里面有很多关于Dagger2的综合教程。但我会向您展示它的用途。并且使用最少。
最终,dagger 将使用注解 @Inject 为变量提供(对对象或值的引用)。
注入通常用于可重用或样板对象,如 Dao、Repository、ViewModel、NetworkAdapter
class SomethingThatRequiresNetwork { // Activity, Fragment
@Inject
MyReusableNetworkAdapter myReusableNetworkAdapter;
String baseUrl; // for example purpose only
SomeDependency someDependency;
void init() {
// @NOTE: DaggerMyExampleComponent is a generated class. It will be red before compilation.
MyExampleComponent MyExampleComponent = DaggerMyExampleComponent.builder().build();
MyExampleComponent.inject(this); // the actual injection happens here
}
// yes, you can just use @Inject on the variables directly but this is another use.
@Inject
void methodInjection(String baseUrl, SomeDependency someDependency) {
this.baseUrl = baseUrl;
this.someDependency = someDependency;
}
}
// ANSWER to the two questions
// this is a pseudocode of the generated code. You do not write this
// MyExampleComponent class
void inject(SomethingThatRequiresNetwork obj) {
// @NOTE: modules are actually instantiated by MyExampleComponent. Not called statically. I just shortened it
obj.myReusableNetworkAdapter = NetModule.provideNetworkAdapter();
obj.methodInjection(NetModule.provideBaseUrl(), SomeModule.provideSomeDependency());
}
// these here are modules that provide by return TYPE
// you write these
@Module
class NetModule {
@Provides
@Singleton
String provideBaseUrl() {
return "www.some-url.com";
}
@Provides
@Singleton // will store the object and reuse it.
// @NOTE: provision can work internally within modules or inter-module. the input here is provided by provideBaseUrl
MyReusableNetworkAdapter provideNetworkAdapter(String baseUrl) {
return new MyReusableNetworkAdapter(baseUrl);
}
}
@Modules
class SomeModule {
@Provides
@Singleton
SomeDependency provideSomeDependency() {
return new SomeDependency();
}
}
// Component. uses modules
@Singleton // .build() will reuse
@Component(modules = {NetModule.class, SomeModule.class})
interface MyExampleComponent {
// the method name doesn't matter
// the class type does matter though.
void inject(SomethingThatRequiresNetwork somethingThatRequiresNetwork);
// some other class that needs injection. @NOTE: I did not give example for this
void inject(SomethingThatRequiresDependency some);
}
注意。这段代码通常是从下往上写的 lol。您开始编写组件,然后是模块,然后是注入。
只需按照此答案顶部的调用,您就会了解 Dagger2 的工作原理。
我正在尝试了解 example 一个应用程序,该应用程序具有使用改造和空间的离线支持:
你可以找到它的代码here:
这个项目正在使用 Dagger2 的依赖注入。我从未使用过它,所以我试图了解它们是如何协同工作的。我理解依赖注入的目的,但是我不理解上面项目的实现。
我在这里找到了关于 Dagger2 的非常好的介绍:
A Friendly Introduction to Dagger 2
我完成了它并掌握了大部分内容。回到我试图理解的实际项目 (link 2)。这对我来说仍然没有意义,原因如下:
接口 AppComponent 有一个使用的方法:
public void inject(MainActivity2ViewModel viewModelModule);
return 类型为空。在 Dagger2 示例项目(link 3 和 4)中,他们使用WeatherReporter getWeatherReporter();
这是有道理的,因为稍后他们调用此方法来获取 WeatherReporter-Instance 并且 Dagger2 在后台管理所有实例化过程。但是如果 return 类型是无效的,我什么也得不到。为什么 return 类型不是对象?MainActivity2ViewModel中有一个
@Inject
:@注入 public void setRepository(GitHubRepository2 存储库){ this.repository = 存储库; }
repository
是 MainActivity2ViewModel
的唯一字段,因此它是一个依赖项。 GitHubRepository2
构造函数有 3 个参数:
@Inject
public GitHubRepository2(GitHubApi api, GitHubDao dao, Executor executor)
对于它们中的每一个,都有一个模块解释如何创建这些对象。但是为什么会有 AppModule 和 NetModule 呢?也许 AppModule 在那里是因为 DaoModule 需要一个 Application 引用,但为什么有 NetModule 以及它在哪里使用?
Android里面有很多关于Dagger2的综合教程。但我会向您展示它的用途。并且使用最少。
最终,dagger 将使用注解 @Inject 为变量提供(对对象或值的引用)。
注入通常用于可重用或样板对象,如 Dao、Repository、ViewModel、NetworkAdapter
class SomethingThatRequiresNetwork { // Activity, Fragment
@Inject
MyReusableNetworkAdapter myReusableNetworkAdapter;
String baseUrl; // for example purpose only
SomeDependency someDependency;
void init() {
// @NOTE: DaggerMyExampleComponent is a generated class. It will be red before compilation.
MyExampleComponent MyExampleComponent = DaggerMyExampleComponent.builder().build();
MyExampleComponent.inject(this); // the actual injection happens here
}
// yes, you can just use @Inject on the variables directly but this is another use.
@Inject
void methodInjection(String baseUrl, SomeDependency someDependency) {
this.baseUrl = baseUrl;
this.someDependency = someDependency;
}
}
// ANSWER to the two questions
// this is a pseudocode of the generated code. You do not write this
// MyExampleComponent class
void inject(SomethingThatRequiresNetwork obj) {
// @NOTE: modules are actually instantiated by MyExampleComponent. Not called statically. I just shortened it
obj.myReusableNetworkAdapter = NetModule.provideNetworkAdapter();
obj.methodInjection(NetModule.provideBaseUrl(), SomeModule.provideSomeDependency());
}
// these here are modules that provide by return TYPE
// you write these
@Module
class NetModule {
@Provides
@Singleton
String provideBaseUrl() {
return "www.some-url.com";
}
@Provides
@Singleton // will store the object and reuse it.
// @NOTE: provision can work internally within modules or inter-module. the input here is provided by provideBaseUrl
MyReusableNetworkAdapter provideNetworkAdapter(String baseUrl) {
return new MyReusableNetworkAdapter(baseUrl);
}
}
@Modules
class SomeModule {
@Provides
@Singleton
SomeDependency provideSomeDependency() {
return new SomeDependency();
}
}
// Component. uses modules
@Singleton // .build() will reuse
@Component(modules = {NetModule.class, SomeModule.class})
interface MyExampleComponent {
// the method name doesn't matter
// the class type does matter though.
void inject(SomethingThatRequiresNetwork somethingThatRequiresNetwork);
// some other class that needs injection. @NOTE: I did not give example for this
void inject(SomethingThatRequiresDependency some);
}
注意。这段代码通常是从下往上写的 lol。您开始编写组件,然后是模块,然后是注入。
只需按照此答案顶部的调用,您就会了解 Dagger2 的工作原理。