Dagger 2 - 如何避免代码重复以注入需要 activity 上下文的依赖项
Dagger 2 - how to avoid code repetition for injecting dependencies that require activity context
我正在处理的项目有许多实用程序 class 需要 activity 上下文。
我不想为每个使用依赖项的 activity 声明一个新的@Provides 方法。即我不想要这个:
@Provides
static Navigator providesNavigator(ActivityOne activity) {
returns new Navigator(activity);
}
// ...and in another module
@Provides
static Navigator providesNavigator(ActivityTwo activity) {
returns new Navigator(activity);
}
因此,我在单个 ActivityUtilitiesModule 中声明这些实用程序,并传递所有其他活动扩展的 BaseActivity。现在我不必声明我的 Navigator 依赖项 x 次。
@Provides
static Navigator(BaseActivity activity) {
return new Navigator(activity);
}
但是,Dagger 不知道如何满足对 BaseActivity 的依赖。这意味着对于每个 Activity 我需要创建一个 provides 方法来满足 BaseActivity 与所使用的特定 Activity 的依赖关系。例如:
@Provides
static BaseActivity providesBaseActivity(ActivityOne activity) {
return activity;
}
这样更好 - 我只需要为每个 activity 重复一个提供程序,而不是为每个 activity 每个实用程序 class 重复一个提供程序,但它仍然感觉像Dagger 设置中不受欢迎的额外步骤,以及使代码更难理解的另一件事。
有没有一种模式可以让我避免为每个 activity 提供这个 BaseActivity 提供商?
请使用构造函数注入。使用 provide*
只调用构造函数的方法只是噪音和需要维护的代码。将 @Inject
添加到 class 构造函数并将可能的范围添加到 class.
@SomePossibleScope
class Navigator {
@Inject
Navigator(Activity activity) { }
}
如果这样做,您可能根本不需要 ActivityUtilitiesModule。
如果您的 class 依赖于 Activity
或 BaseActivity
,那么您需要提供它。是的,你必须以某种方式告诉 Dagger。
如果要使用抽象 class 或接口,则应改用 @Binds
。
@Binds BaseActivity bindsBaseActivity(ActivityOne activity);
与@Provides
相比,Dagger 可能会进一步优化此代码,减少方法调用和对象创建的次数,并减少几行代码。
我不知道为什么你的 Utils 依赖于 Activity
,但如果他们只需要一个 Context
那么你也可以只向他们提供应用程序上下文而不需要绑定或提供您的实际 Activity.
我个人只是将当前的 Activity 绑定到它使用上述语法实现的类型。而且,如果您正确使用构造函数注入,那往往是您在我的模块中找到的唯一代码行,使它们非常可读。
我正在处理的项目有许多实用程序 class 需要 activity 上下文。
我不想为每个使用依赖项的 activity 声明一个新的@Provides 方法。即我不想要这个:
@Provides
static Navigator providesNavigator(ActivityOne activity) {
returns new Navigator(activity);
}
// ...and in another module
@Provides
static Navigator providesNavigator(ActivityTwo activity) {
returns new Navigator(activity);
}
因此,我在单个 ActivityUtilitiesModule 中声明这些实用程序,并传递所有其他活动扩展的 BaseActivity。现在我不必声明我的 Navigator 依赖项 x 次。
@Provides
static Navigator(BaseActivity activity) {
return new Navigator(activity);
}
但是,Dagger 不知道如何满足对 BaseActivity 的依赖。这意味着对于每个 Activity 我需要创建一个 provides 方法来满足 BaseActivity 与所使用的特定 Activity 的依赖关系。例如:
@Provides
static BaseActivity providesBaseActivity(ActivityOne activity) {
return activity;
}
这样更好 - 我只需要为每个 activity 重复一个提供程序,而不是为每个 activity 每个实用程序 class 重复一个提供程序,但它仍然感觉像Dagger 设置中不受欢迎的额外步骤,以及使代码更难理解的另一件事。
有没有一种模式可以让我避免为每个 activity 提供这个 BaseActivity 提供商?
请使用构造函数注入。使用 provide*
只调用构造函数的方法只是噪音和需要维护的代码。将 @Inject
添加到 class 构造函数并将可能的范围添加到 class.
@SomePossibleScope
class Navigator {
@Inject
Navigator(Activity activity) { }
}
如果这样做,您可能根本不需要 ActivityUtilitiesModule。
如果您的 class 依赖于 Activity
或 BaseActivity
,那么您需要提供它。是的,你必须以某种方式告诉 Dagger。
如果要使用抽象 class 或接口,则应改用 @Binds
。
@Binds BaseActivity bindsBaseActivity(ActivityOne activity);
与@Provides
相比,Dagger 可能会进一步优化此代码,减少方法调用和对象创建的次数,并减少几行代码。
我不知道为什么你的 Utils 依赖于 Activity
,但如果他们只需要一个 Context
那么你也可以只向他们提供应用程序上下文而不需要绑定或提供您的实际 Activity.
我个人只是将当前的 Activity 绑定到它使用上述语法实现的类型。而且,如果您正确使用构造函数注入,那往往是您在我的模块中找到的唯一代码行,使它们非常可读。