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

Dagger2模块的“接口”?

如何解决《Dagger2模块的“接口”?》经验,为你挑选了1个好方法。

我是Dagger 2的新手,我正在寻找一种具有“可配置组件”的方法。

本质上,这就是我想要实现的目标:

public interface ErrorReporter{
   ...
}

public class ConsoleErrorReporter implements ErrorReporter{
   ... // Print to System.err
}

public class DialogErrorReporter implements ErrorReporter{
   ... // Show modal dialog to user
}


@Module
public interface UIModule{
    @Provides
    ErrorReporter provideErrorReporter();
}

@Module
public class ConsoleUIModule{
    @Override
    @Provides
    ErrorReporter provideErrorReporter(ConsoleErrorReporter cer){
        return cer;
    }
}


@Module
public class GraphicalUIModule{
    @Override
    @Provides
    ErrorReporter provideErrorReporter(DialogErrorReporter  der){
        return der;
    }
}

@Component(modules = {UIModule.class, OtherUniversalModule.class})
public interface ApplicationComponent{
    ErrorReporter errorReporter();
}


void main(String[] args){
    final UIModule uiModule;
    if(args.length == 1 && args[0].equals("gui")){
        uiModule = new GraphicalUIModule();
    }else{
        uiModule = new ConsoleUIModule();
    }

    DaggerApplicatiOnComponentdac= DaggerApplicationComponent.builder()
                                       .uiModule(uiModule).build();
    dac.errorReporter().showError("Hello world!");
}

@Provides methods cannot be abstract不幸的是,以上操作均因接口和抽象类而失败。我还尝试了非抽象基类的具体实现,这些实现返回null,然后在子类中覆盖它们。但是,这也失败了@Provides methods may not override another method

简而言之,我想为模块定义合同,并在运行时选择不同的模块。我知道Dagger 2的编译时间可以验证对象图,但是如果我有一个定义明确的合同,那仍然应该可行吗?还是我被迫使用两个用户界面的重复代码创建两个不同的组件?我还缺少其他解决方案吗?



1> David Medenj..:

我认为以这种方式使用模块是不可能的,因为...

假设您的类具有以下两个构造函数

@Inject ConsoleErrorReporter(Console console);

@Inject DialogErrorReporter(Graphics graphics);

这意味着ConsoleUIModule将需要一个ConsoleDialogErrorReporter一个Graphics对象来创建其各自的实现。ErrorReporter

但是如果匕首只知道 UIModule因为您在那儿使用了接口……那么……它不能提供任何依赖,因为它不知道其中的任何一个。

而且,如果您不知道在编译时建立依赖关系图的依赖关系将无法工作。而且即使没有匕首也不会编译,因为provideErrorReporter(ConsoleErrorReporter cer)不会覆盖provideErrorReporter()


您可以并且应该做的是使用不同的组件。因为组件是真正知道如何提供东西的东西。组件已经是接口了,这就是您想要的,对吧?

您可以具有组件依赖关系,其中一个组件依赖于另一个。例如DependentComponent,提供的NeedsErrorReporter,需要实现ErrorReporter。我们还依赖于接口,而不是实际的组件(毕竟,这就是您想要的,对吧?)

然后,您可以通过实际的组件来实现该接口,并且每个组件都有其各自的模块(甚至可能还有其他依赖性)。最后,您将拥有一个可以切换的组件,并将提供正确封装的对象的不同版本!

@Component(dependencies = UIComponent.class) /* <- an interface! */
interface DependentComponent {
  NeedsErrorReporter needsErrorReporter();
}

class NeedsErrorReporter {
  @Inject public NeedsErrorReporter(ErrorReporter reporter) { }
}


/* this is _not_ a component, but a simple interface! */
interface UIComponent {
  ErrorReporter errorReporter();
}


/* Console */
@Component(modules = ConsoleUIModule.class)
interface ConsoleUIComponent extends UIComponent { }

@Module interface ConsoleUIModule {
  @Binds ErrorReporter provideErrorReporter(ConsoleErrorReporter cer);
}

/* Graphic */
@Component(modules = GraphicalUIModule.class)
interface GraphicUIComponent extends UIComponent { }

@Module interface GraphicalUIModule {
  @Binds ErrorReporter provideErrorReporter(DialogErrorReporter der);
}

/* The error reporter variants */
interface ErrorReporter {
}

class ConsoleErrorReporter implements ErrorReporter {
  @Inject public ConsoleErrorReporter() { }
}

class DialogErrorReporter implements ErrorReporter {
  @Inject public DialogErrorReporter() { }
}

现在您所要做的就是选择正确的组件;)

DaggerDependentComponent.builder().uIComponent(DaggerConsoleUIComponent.create()).build();
    // or
DaggerDependentComponent.builder().uIComponent(DaggerGraphicUIComponent.create()).build();


推荐阅读
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
  • Android源码中的Builder模式及其作用
    本文主要解释了什么是Builder模式以及其作用,并结合Android源码来分析Builder模式的实现。Builder模式是将产品的设计、表示和构建进行分离,通过引入建造者角色,简化了构建复杂产品的流程,并且使得产品的构建可以灵活适应变化。使用Builder模式可以解决开发者需要关注产品表示和构建步骤的问题,并且当构建流程发生变化时,无需修改代码即可适配新的构建流程。 ... [详细]
  • 今天来法分析AlertDialogcancel()销毁窗口流程。前面文章说了其实activity和dialog都是通过window对象来管理视图的。所以我们可以从AlertDialog销毁过程来了 ... [详细]
  • 本文整理了Java中javax.lang.model.util.Types.getNullType()方法的一些代码示例,展示了Types.getNullT ... [详细]
  • Android Studio中使用apt
    AndroidStudio中使用apt一、前言你还在对着枯燥的重复代码一味复制粘贴吗?这样跟搬砖有何区别?你是否曾想过:你用代码编写出一个自动化的APP,但为何代码本身却缺少了活力 ... [详细]
  • dagger2简单使用与理解笔记
    文章目录使用dagger2好处具体案例查看github1.使用dagger2注入基本使用流程概念2.dagger2中各种注解基本使用引入dagger20.写两个对象用来实际操作的1 ... [详细]
  • RxCache是使用注解为Retrofit加入二级缓存(内存,磁盘)的缓存库。开头膜拜大神项目地址:RxCacheRxCache使用方法定义接口publicinterfaceCac ... [详细]
  • java注解机制_Java注解机制基础
    最近整体研究了一下ButterKnife这个框架,顺带着系统回顾梳理了一遍Java注解相关的知识点。本文大致整理了一下注解的几个核心部分,内容参考了很多 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 推荐:看到如此多的MVP+Dagger2+Retrofit+Rxjava项目,轻松拿star,心动了吗?看到身边的朋友都已早早在项目中使用这些技术,而你还不会,失落吗?MVPArm ... [详细]
  • QuadTilingTimeLimit:1000MSMemoryLimit:65536KTotalSubmissions:5008Accepted:2269DescriptionT ... [详细]
  • Use从句的语法一、Use从句列出了所有使用到的单元的名称(不是源文件的名称)。Use从句出现在以下位置:-->.dpr文件的工程名称之后。-->.pas文 ... [详细]
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社区 版权所有