我正在尝试通过改型和空间来了解具有离线支持的应用的example:
您可以找到它的代码here:
该项目正在Dagger2中使用依赖项注入。我从未使用过它,因此我试图了解它们如何协同工作。我了解依赖项注入的目的,但不了解上述项目的实施。
我在这里找到了Dagger2的很好的介绍:
A Friendly Introduction to Dagger 2
我研究了其中的大部分内容。回到我试图理解的实际项目(链接2)。这对我来说仍然没有意义,这就是原因:
AppComponent接口具有一种使用的方法:
public void inject(MainActivity2ViewModel viewModelModule);
返回类型为void。在Dagger2示例项目(链接3和4)中,他们使用WeatherReporter getWeatherReporter();
是有意义的,因为后来他们调用此方法来获取WeatherReporter-Instance,并且Dagger2在后台管理所有实例化过程。但是如果返回类型为空,我什么也没得到。为什么返回类型不是对象?
MainActivity2ViewModel中有一个@Inject
:
@注入 公共无效setRepository(GitHubRepository2存储库){ this.repository =储存库; }
repository
是MainActivity2ViewModel
的唯一字段,因此它是一个依赖项。 GitHubRepository2
构造函数具有3个参数:
@Inject
public GitHubRepository2(GitHubApi api, GitHubDao dao, Executor executor)
每个模块都有一个模块说明如何创建这些对象。但是为什么会有AppModule和NetModule?也许有AppModule,是因为DaoModule需要一个Application引用,但是为什么要有NetModule?在哪里使用它?
答案 0 :(得分:1)
关于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);
}
注意。这段代码通常是从下往上写的。您开始编写组件,然后是模块,然后是注入。
只需遵循此答案顶部的电话,您就会了解Dagger2的工作原理。