组件应该是“大DI提供商”,提供一切为了一个特定的范围。
例如,您可以有一个SingletonComponent
与@Singleton
作用域,每个添加的模块至少有一个@Singleton
作用域提供程序方法。
@Singleton
@Component(modules={NetworkingModule.class, DatabaseModule.class, MapperModule.class, UtilsModule.class})
public interface SingletonComponent {
// provision methods
OkHttpClient okHttpClient();
RealmHolder realmHolder();
// etc.
}
您可以为每个模块定义供应方法。
public interface DatabaseComponent {
RealmHolder realmHolder();
}
public interface NetworkingComponent{
OkHttpClient okHttpClient();
}
在这种情况下,你不得不
@Singleton
@Component(modules={NetworkingModule.class, DatabaseModule.class, MapperModule.class, UtilsModule.class})
public interface SingletonComponent
extends NetworkingComponent, DatabaseComponent, MapperComponent, UtilsComponent {
// provision methods inherited
}
在一个模块中,可以指定一个工厂方法(“提供方法”),指定了如何创建一个特定的依赖类型。
例如,
@Module
public class NetworkingModule {
@Provides
@Singleton
OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()./*...*/.build();
}
@Provides
@Singleton
Retrofit retrofit(OkHttpClient okHttpClient) {
// ...
}
}
你可以想象@Singleton
范围为春节会给你很大的DI容器。
您还可以使用@Inject
带注释的构造函数提供该类的实例。这可以接收组件中的任何类,该组件可以通过该范围组件的模块中的提供者方法实例化该组件(当然还包括无范围的依赖关系)。
@Singleton
public class MyMapper {
@Inject
public MyMapper(RealmHolder realmHolder, OkHttpClient okHttpClient) { // totally random constructor for demo
}
}
或
@Singleton
public class MyMapper {
@Inject
RealmHolder realmHolder;
@Inject
OkHttpClient okHttpClient;
@Inject
public MyMapper() {
}
}
那么这将是组件中可用,你甚至可以做出规定的方法为它使可继承的组件的依赖:
@Singleton
@Component(modules={...})
public interface SingletonComponent {
MyMapper myMapper();
}
随着Dagger2,你也可以添加盟友创建“subscoped组件”,它继承了从给定范围的组件提供的所有依赖项。
例如,您可以继承所有@Singleton
作用域组件,但您仍然可以为每个新作用域创建新的作用域依赖项,例如@ActivityScope
。
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}
然后,您可以创建使用两种子,或组件的依赖subscoped组件。
。
@ActivityScope
@Subcomponent(modules={MainActivityModule.class})
public interface MainActivityComponent {
MainPresenter mainPresenter();
}
那么这可以在其父创建范围的组件:
@Singleton
@Component(modules={...})
public interface SingletonComponent {
MainActivityComponent mainActivityComponent(MainActivityModule module);
}
然后你就可以使用单独组件来实例化这样的:
SingletonComponent singletonComponent = DaggerSingletonComponent.create();
MainActivityComponent mainActivityComponent = singletonComponent.mainActivityComponent(new MainActivityModule(mainActivityHolder));
。
@ActivityScope
@Component(dependencies={SingletonComponent.class}, modules={MainActivityModule.class})
public interface MainActivityComponent extends SingletonComponent {
MainPresenter mainPresenter();
}
对于这个工作,你必须指定在superscoped部件供给方法。
然后就可以像这样实例化这个:
@Inject
注释构造参数
@Inject
: SingletonComponent singletonComponent = DaggerSingletonComponent.create();
MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder()
.singletonComponent(singletonComponent)
.mainActivityModule(new MainActivityModule(mainActivityHolder))
.build();
在Dagger2,可以因此无论是通过获得的依赖关系clas上的注释字段与@Inject
SES注释构造
- 从通过在组件中定义的手动场注入法
@Component
规定方法
- (用于类不能创建使用
@Inject
注释的构造函数)
手册字段注射可能发生像类MainActivity
,你自己并没有创建。
手动现场注入仅注入要注入的特定类别。基类不会自动注入,他们需要在组件上调用.inject(this)
。
它的工作原理是这样的:
@ActivityScope
@Subcomponent(modules={MainActivityModule.class})
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
}
然后,你可以这样做:
public class MainActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder()
.singletonComponent(getSingletonComponent())
.mainActivityModule(new MainActivityModule(this))
.build(); // ensure activity `holder` instead, and retain component in retained fragment or `non-configuration instance`
mainActivityComponent.inject(this);
}
}
这使得它更清晰,我仍然有一些疑虑,但我会尝试从这里解决它。我唯一的问题是 - 我仍然需要为我的应用程序中的每个片段/活动创建一个组件/子组件? –
你不**有**,我做了3个应用程序只使用一个'@ Singleton'组件,没有其他组件。 – EpicPandaForce