【问题标题】:What is the difference between empty constructor module and a module which provides dependency with a parameter in Dagger 2?空构造函数模块和在 Dagger 2 中提供参数依赖的模块有什么区别?
【发布时间】:2015-11-23 20:34:35
【问题描述】:

我正在尝试通过在一个小示例中实现 Dagger 2 来学习 DI。我得到了这个概念 @Module 和 @Component。 @Component 将@Module 与需要注入依赖的类绑定。

Dagger 生成 Dagger,它有一个 Builder 类提供和初始化 依赖关系。

所以我尝试了一些场景以更好地理解 Dagger 2。我有一些问题,但我会去的 现在有一个。

我需要注入 DatabaseHelper 类。我为此创建了 DatabaseModule 类。我也发现 我可以跳过该类并在我的主 ApplicationModule 中添加一个方法来提供 DatabaseHelper。去做 我不能将 DatabaseModule 添加到 ApplicationComponent 模块列表中。无论如何,我保留了 DatabaseModule 在 ApplicationComponent 模块列表中并从 ApplicationModule 中删除该方法。回到我的问题。

在创建 DatabaseModule 类时,我有两个选择。这是第一个。

@Module
public class DatabaseModule {

    private Application app;

    public DatabaseModule(Application app) {
        this.app = app;
    }

    @Singleton
    @Provides
    public DatabaseHelper provideDBHelper() {
        return new DatabaseHelper(app.getApplicationContext());
    }
}

第二个选项是,

@Module
public class DatabaseModule {

    @Singleton
    @Provides
    public DatabaseHelper provideDBHelper(Application app) {
        return new DatabaseHelper(app.getApplicationContext());
    }
}

如果我使用第二种方法,我不需要调用组件生成器的方法.databaseModule() as Dagger 照顾它。我猜这是微不足道的。

我的问题是 - 这两者有什么区别?我应该使用哪一个?有什么优点 以及每种方法的缺点。另外,如果我想在 Application 不是的类中注入 DatabaseHelper 可访问,我可以用第一选择吗? (因为它提供了一个单例)。

如果我做错了什么并且需要更改其他内容,请指出。这是我的 ApplicationModule 和 ApplicationComponent 类。

@Module
public class ApplicationModule {
    private Application mApplication;

    public ApplicationModule(Application app) {
        mApplication = app;
    }

    @Singleton
    @Provides
    Application provideApplication() {
        return mApplication;
    }
}

应用组件类

@Singleton
@Component(
        modules = {
            ApplicationModule.class,
            DatabaseModule.class
        }
)
public interface ApplicationComponent {
    Application getApplication();
    void inject(MyApplication app);
    DatabaseHelper getDBHelper();
}

【问题讨论】:

    标签: java android dependency-injection dagger-2


    【解决方案1】:

    这听起来很奇怪,但是在其构造函数中接收参数的@Module 和在其构造函数中不接收参数的@Module 之间的区别在于其中一个接收参数而另一个一个没有。

    是的,我知道这是同义反复。如果模块有必要使用它,则应该提供构造函数参数(例如,如果您需要上下文,您可能希望在给定范围内向模块提供应用程序/活动)。如果它不需要外部参数,那么给它一个没有意义。

    关键区别在于,带有外部参数的模块必须在构造时显式地赋予Dagger___Component.builder() 方法。如果您的所有模块都未参数化,那么您可以改用 Dagger___Component.create() 方法,它会为您创建每个未参数化的模块。

    如果你想创建一个不带参数的ApplicationModule,那么你可能不得不这样做

    public enum ApplicationHolder {
        INSTANCE;
    
        private CustomApplication customApplication;
    
        void setApplication(CustomApplication customApplication) {
            this.customApplication = customApplication;
        }
    
        public CustomApplication getApplication() {
            return application;
        }
    }
    
    public class CustomApplication extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
            ApplicationHolder.INSTANCE.setApplication(this);
        }
    }
    
    @Module
    public class ApplicationModule {
        @Provides
        public CustomApplication customApplication() {
            return ApplicationHolder.INSTANCE.getApplication();
        } 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      • 2011-06-13
      • 1970-01-01
      • 2012-08-29
      • 1970-01-01
      • 1970-01-01
      • 2019-08-16
      相关资源
      最近更新 更多