Dagger 2构造函数注入在模块调用之前没有发生

时间:2017-07-20 19:26:39

标签: android dependency-injection dagger-2 dagger

我正在学习Dagger 2并正在开发一款应用。我有一个设置模块,它取决于依赖于共享首选项管理器的设置管理器。我的问题是我的设置模块在调用之前没有注入设置管理器。该设置管理器需要一个SharedPrefsManager,它也没有被注入任何地方。

我做错了什么?

依赖性顺序的片段:

@Module
public class SettingsModule {   
    @Inject SettingsManager manager;

    @Provides
    @TimeControl
    int[] provideResetTime(){
        return manager.getResetTime();
    }

    @Provides
    @ThemeControl
    int provideThemeID(){
        return manager.getTheme();
    }
}

取决于设置管理器:

public class SettingsManager{
    private SharedPreferencesManager manager;
    @Inject
    SettingsManager(SharedPreferencesManager manager){
        this.manager = manager;
    }
}

取决于共享首选项管理器:

public class SharedPreferencesManager {
    private static SharedPreferencesManager instance = null;
    public static SharedPreferencesManager getInstance(){return instance;}
    String prefsKey = "SHAREDPREFSKEY";
    SharedPreferences sharedPrefs = null;
    Context applicationContext = null;

    @Inject
    SharedPreferencesManager(@ApplicationContext Context applicationContext){
        this.prefsKey = prefsKey;
        this.applicationContext = applicationContext;
        sharedPrefs = applicationContext.getSharedPreferences(prefsKey,Context.MODE_PRIVATE);
        instance = this;
    }
}

2 个答案:

答案 0 :(得分:1)

@Module
public class SettingsModule {   
    @Inject SettingsManager manager;

    @Provides
    @TimeControl
    int[] provideResetTime(){
        return manager.getResetTime();
    }

    @Provides
    @ThemeControl
    int provideThemeID(){
        return manager.getTheme();
    }
}

应该是

@Module
public class SettingsModule {   
    @Provides
    @TimeControl
    int[] resetTime(SettingsManager manager) {
        return manager.getResetTime();
    }

    @Provides
    @ThemeControl
    int themeId(SettingsManager manager) {
        return manager.getTheme();
    }
}

请注意您的提供商没有范围,因此(AFAIK)获得themeId()的通话和获得resetTime()的通话很可能每次都会创建一个新的SettingsManager

因此可能希望将@Singleton放在您提供的课程上。

@Singleton
public class SharedPreferencesManager {
    private SharedPreferences sharedPrefs = null;
    String prefsKey = "SHAREDPREFSKEY";
    Context applicationContext = null;

    @Inject
    SharedPreferencesManager(Context applicationContext) {
        this.applicationContext = applicationContext;
        sharedPrefs = applicationContext.getSharedPreferences(prefsKey, Context.MODE_PRIVATE); // why isn' this in a module?
    }
}

@Singleton
public class SettingsManager{
    private SharedPreferencesManager manager;
    @Inject
    SettingsManager(SharedPreferencesManager manager){
        this.manager = manager;
    }
}

答案 1 :(得分:0)

我认为您不应该在模块中添加@Inject注释,因为它们构建为创建依赖项并且仅通过对象图或简单构造函数接收其他依赖项。

以下是一个示例,说明如何避免模块中的@Inject注释以及之后的构造函数注入器。

<强> SettingsModule.java

@Module
public class SettingsModule {

    @Provides
    @TimeControl
    int[] provideResetTime(SettingsManager manager) {
        return manager.getResetTime();
    }

    @Provides
    @ThemeControl
    int provideThemeID(SettingsManager manager) {
        return manager.getTheme();
    }

    @Provides
    SettingsManager provideSettingsManager(SharedPreferencesManager sharedPreferencesManager) {
        return new SettingsManager(sharedPreferencesManager);
    }

    @Provides
    SharedPreferencesManager provideSharedPreferencesManager(@ApplicationContext Context context) {
        return new SharedPreferencesManager(context);
    }
}

<强> SettingsManager.java

public class SettingsManager {
    private SharedPreferencesManager manager;

    SettingsManager(SharedPreferencesManager manager) {
        this.manager = manager;
    }
}

<强> SharedPreferencesManager.java

public class SharedPreferencesManager {
    private static SharedPreferencesManager instance = null;
    private SharedPreferences sharedPrefs = null;
    String prefsKey = "SHAREDPREFSKEY";
    Context applicationContext = null;

    SharedPreferencesManager(Context applicationContext) {
        this.applicationContext = applicationContext;
        sharedPrefs = applicationContext.getSharedPreferences(prefsKey, Context.MODE_PRIVATE);
        instance = this;
    }

    public static SharedPreferencesManager getInstance() {
        return instance;
    }
}

通过这种方式,您可以将所有注入逻辑留给您的模块,具体类别不必担心自己注入类。