我试图学习如何使用dagger2。你是否应该为你拥有的每个模块制作一个组件(然后将组件组合在"超级组件")?
我有2个模块可以使用,以及曾经拥有单独组件的模块。然后我添加了一个额外的模块(没有组件),在新模块中,我的@Inject似乎不起作用。
我怎样才能将AppModule注入我的新GyroModule?
我的新人"陀螺"模块:
@Module
public class GyroModule implements SensorEventListener {
@Inject AppModule _appModule; // NULL
private SensorEvent _lastReading;
private SensorManager _sensorManager;
private Sensor _gyro;
@Inject
public GyroModule() {
initialize();
}
@Provides
@Singleton
public GyroModule provideGyroModule() {
return this;
}
我的主要活动:
public class MainActivity extends LocationAwareActivity {
@Inject PointOfInterestModule pointOfInterestModule; // OK
@Inject LocationModule locationModule; // OK
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((AllTheLocateApplication) getApplication()).getAppComponent().inject(this);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, AugmentedActivity.class);
startActivity(intent);
}
}
我的"上帝"组件(以及应用程序中的唯一组件):
@Singleton
@Component(modules={AppModule.class,
PointOfInterestModule.class,
LocationModule.class,
GyroModule.class})
public interface IAppComponent {
void inject(AllTheLocateApplication application);
void inject(MainActivity mainActivity);
void inject(AugmentedActivity augmentedActivity);
void inject(AppModule appModule);
void inject(PointOfInterestModule pointOfInterestModule);
void inject(LocationModule locationModule);
void inject(GyroModule gyroModule);
}
我的AppModule
@Module
public class AppModule {
AllTheLocateApplication mApplication;
public AppModule(AllTheLocateApplication application) {
mApplication = application;
}
public AllTheLocateApplication getApplication() {
return mApplication;
}
@Provides
@Singleton
AppModule providesAppModule() {
return this;
}
}
答案 0 :(得分:4)
你是否应该为你拥有的每个模块制作一个组件[...]
没有
[...](然后将组件组合在"超级组件")?
没有
模块应该是您的B计划,并且 - 除非确实有必要,否则不得不费力地避免使用。有三个理由说明您需要使用它们:
如果不是至少其中一个是真的,请不要使用模块。
模块与注射无关。他们不会 - ,不应该 - 包含您的业务逻辑。 他们所做的就是提供那些无法访问或构造符注入的对象。他们无法注入,也无法注入。如果一个对象依赖于另一个对象,则将其作为方法中的参数。如果你不想自己调用构造函数,那么dagger只会为你创建模块,因为有一个no-args构造函数。
initialize()
方法不应该是模块的一部分。如果您需要提供A和A需求,它应如下所示:
@Provides
provideA(B b) {
A a = new A();
a.setB(b);
a.doMoreInitializationThatMustBeDoneNow();
return a;
}
B是否来自同一模块,不同模块,父组件,组件依赖或构造函数注入不是您的概念。模块不需要彼此了解,匕首只会用B调用你的方法。然后你只需要返回A.
我不知道您要对代码示例做什么。模块 不 是您业务逻辑的一部分。他们提供依赖项。您应 不 依赖于业务逻辑中的模块。也不应该包括getter,setter或更新任何对象。模块创建一个对象并初始化它。他们 不 以任何其他方式与之互动。
通过创建单个java文件来玩匕首。添加一些模块。放入一个尝试注入一些依赖项的类。你可以看到事情是如何编译的(或者不是)。也许可以尝试阅读更多关于匕首的教程,以便更好地理解核心概念。