热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Dagger2注入构造函数

如何解决《Dagger2注入构造函数》经验,为你挑选了1个好方法。

我开始在我正在开发的应用程序中使用Dagger 2,但我对Dagger 2的工作方式有一些疑问.

我得到了@Provides方法和@Inject注释背后的所有逻辑来初始化你的依赖关系,但@Inject注释到类构造函数有点让我头疼.

例如:

我的应用程序,我有一个模块定义,ContextModule,以检索我的应用程序的上下文:

ContextModule.java

@Module
public class ContextModule {

    private final Context context;

    public ContextModule(Context context) {
        this.cOntext= context;
    }

    @Provides
    public Context context() {
        return this.context;
    }
}

我的BaseActivityComponent使用此模块:

BaseActivityComponent.java

@BaseActivityScope
@Component(modules = ContextModule.class)
public interface BaseActivityComponent {
    void injectBaseActivity(BaseActivity baseActivity);
}

到目前为止很好..然后我有一个AuthController类,这取决于上下文,我想在我的BaseActivity中注入它.所以在我的AuthControllers.class中我有类似的东西:

public class AuthController {

    private Context context;

    @Inject
    public AuthController(Context context) {
        this.cOntext= context;
    }

    public void auth() {
        // DO STUFF WITH CONTEXT
    }
}

我将它注入我的BaseActivity中,如:

public class BaseActivity extends AppCompatActivity {

    @Inject
    AuthController authController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        BaseActivityComponent compOnent= DaggerBaseActivityComponent.builder()
            .contextModule(new ContextModule(this))
            .build();

        component.injectBaseActivity(this);

        authController.auth();

    }
}

现在我的问题是,dagger如何知道我的AuthControllers是BaseActivity的依赖?只是声明

@Inject
AuthController authController;

它就像我创建一个ControllerModule一样:

@Module(includes = ContextModule.class)
public class ControllerModule {

    @Provides
    AuthController authController(Context context) {
        return new AuthController(context);
    }

}

然后在我的BaseActivityComponent中,我将添加我的AuthController getter并将我的依赖模块更改为ControllersModule:

@BaseActivityScope
@Component(modules = ControllersModule.class)
public interface BaseActivityComponent {

    void injectBaseActivity(BaseActivity baseActivity);

    AuthController getAuthController();
}

当我调用injectBaseActivity(this)时,它"告诉"匕首所有@Inject注释都是我的类的依赖项,然后它搜索我的项目以获取与该类型匹配的@Inject注释构造函数?

我认为关于Dagger 2的一个好处是模块文件可以用作我的依赖关系三的"文档".但是如果只是在我控制的所有构造函数中添加@Inject,将来不会有点混乱,因为你不知道实际上取决于什么?(我的意思是,你知道什么取决于什么,你只需要浏览很多文件才能真正找到答案)

在构造函数中使用@Inject注释或何时在Modules文件中添加@Provides方法时,是否有任何最佳实践?我在构造函数中使用@Inject得到了我不需要在我的Module文件中更改构造函数定义,但是有任何缺点吗?

谢谢.



1> David Medenj..:

当我调用injectBaseActivity(this)时,它"告诉"匕首所有@Inject注释都是我的类的依赖项,然后它在我的项目中搜索匹配该类型的@Inject注释构造函数?

究竟.但是当你打电话时却没有完成injectBaseActivity,但这一切都发生在编译期间.这是注释处理的一种方式(另一种方法是在运行时使用反射).

在构建项目时,您在build.gradle文件中包含的(作为依赖项)的dagger-annotation-processor将通过注释注释的所有字段,类等的列表进行调用,@Inject并使用它构建依赖关系图.然后它解析图形,生成源代码,提供图形上项目的所有依赖项.

injectBaseActivity只执行之前生成的代码,并将所有依赖项分配给您的对象.它是正确的源代码,您可以阅读和调试.

这是一个简单的编译步骤 - 性能和验证.(例如,如果您有一些依赖循环,则会出现编译错误)


dagger如何知道我的AuthControllers是BaseActivity的依赖?

@Inject
AuthController authController;

通过注释场@Inject匕首知道你想要一个AuthController.到现在为止还挺好.现在,dagger将寻找一些方法来提供控制器,在组件内查找它,组件依赖项和组件模块.它还将查看该类是否可以自己提供,因为它知道它的构造函数.

如果您不在任何模块中包含它,匕首如何知道对象构造函数?

@Inject
public AuthController(Context context) { /**/ }

通过使用注入来注释构造函数,您还告诉dagger有一个被调用的类AuthController,您需要一个上下文来实例化它.它与将其添加到模块基本相同.

@Provides如果您没有源代码只是将@Inject注释添加到构造函数,或者对象需要进一步初始化,则应使用模块方法.或者在你的情况下......

[...]模块文件可以用作我的依赖树的"文档"[...]

是的,当然你可以这样做.但随着项目的增长,您将不得不维护许多不必要的代码,因为在构造函数上使用简单的注释也可以完成相同的操作.

在构造函数中使用@Inject注释或何时在Modules文件中添加@Provides方法时,是否有任何最佳实践?

如果要为不同的上下文提供不同的版本(例如,以两种不同的方式实现接口),还有一个@Binds注释告诉dagger您希望将哪个类作为实现提供.

除此之外,我相信你应该尽可能使用构造函数注入.如果发生了变化,您不必触及代码的任何其他部分,只需要编写的代码就少,因此可以包含错误的地方更少.

Dagger也可以并且通过了解更多来优化很多,如果你实现不必要的代码,它将不得不处理你引入的开销


当然,最终完全取决于您认为最好的.毕竟,必须使用你的代码;)


@saiedVanguard有可能:`class A @Inject constructor(...)`
推荐阅读
author-avatar
淡逸幽悠
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有