java - 将基于 Guice 的项目迁移到 Dagger

标签 java guice dagger-2

我有一个使用 vanilla Guice 的基于 Guice 的项目; 没有 Assisted-Inject,没有 AOP,没有扩展 Guice 的额外插件,等等。 为了在 Android 上更轻松地运行它,Dagger 似乎是一个更好的解决方案。 每个类都有一个依赖项和一个带有 @Inject 注释的构造函数。 没有使用字段或方法注入(inject)。

这些模块非常简单(使 Guice 变得矫枉过正)并且主要包含如下绑定(bind):

class SomethingModule extends AbstractModule {

  protected void configure() {
    Bind(Handler.class)
      .annotatedWith(Names.named("something"))
      .to(SomeImplementation.class);
    }
  }

}

然后像下面这样使用:

Injector inj = Guice.createInjector(new SomethingModule());
... = inj.getInstance(SampleInterface.class);
// and rest of the code.

不幸的是, 我无法理解Daggers terminology . 你能指导我将 Guice 模块直接翻译/转换为 Dagger 模块吗?

Dagger 有:

  • Dagger 的组件。
  • Dagger 的模块。
  • @Provides
  • @Inject

Guice 有:

  • @Inject
  • @Named(或任何自定义注解,如果实现正确的话)。
  • 我们的模块扩展 AbstractModule
  • @Provides 在模块中。
  • Guice Injector 从模块创建。

它们之间有什么关系?

更新:除了 EpicPandaForce 的精彩回答外,these slides也可以提供帮助。

最佳答案

Bind(Handler.class)
.annotatedWith(Names.named("something"))
.to(SomeImplementation.class);

将转化为

@Module
public class SomethingModule {
    @Provides
    @Named("something")
    //scope if needed
    public Handler handler() {
        return new SomeImplementation();
    }
}

它将绑定(bind)到“Injector”(组件):

@Component(modules={SomethingModule.class})
//scope if needed
public interface SomethingComponent {
    @Named("something")
    Handler handler();

    void inject(ThatThingy thatThingy);
}

这是您必须使用 APT 生成的构建器创建的“注入(inject)器”:

SomethingComponent somethingComponent = DaggerSomethingComponent.builder()
                                           .somethingModule(new SomethingModule()) //can be omitted, has no params
                                           .build();
somethingComponent.inject(thatThingy);

那个东西在哪里

public class ThatThingy {
    @Inject
    @Named("something")
    Handler handler;
}

组件通常存在于每个作用域,因此例如@ApplicationScope一个“注入(inject)器”(组件)。可以通过子组件和组件依赖关系来实现范围界定。

重要的事实是,组件具有提供方法(如果您使用组件依赖项,它们是继承到子范围组件的依赖项)和 void inject(X x); 格式的方法。这是现场注入(inject)每种混凝土类型所必需的。例如,一个基类只能注入(inject)自身不能它的子类。但是,您可以编写一个名为 protected abstract void injectThis() 的方法,它也会在子类上调用 .inject(this)

因为我还没有真正使用过 Guice,所以我不确定我是否遗漏了什么。我想我忘记了构造函数注入(inject),这是一个问题,因为虽然 Dagger 确实支持它,但它无法重新配置。对于重新配置,您必须使用模块,并自己在构造函数中进行注入(inject)。

@Module(includes={ThoseModule.class, TheseModule.class})
public abstract class SomethingModule {
    @Binds
    abstract Whatever whatever(WhateverImpl impl);
}

@Singleton
public class WhateverImpl implements Whatever {
    Those those;
    These these;

    @Inject
    public Whatever(Those those, These these) {
        this.those = those;
        this.these = these;
    }
}

@Component(modules={SomethingModule.class})
@Singleton
public interface SomethingComponent {
    These these();
    Those those();
    Whatever whatever();
}

关于java - 将基于 Guice 的项目迁移到 Dagger,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36483039/

相关文章:

android - Kotlin 中的 Dagger 2 Unresolved reference DaggerXXXSub

logging - Dagger:注入(inject)名为Logger?

java - 如何列出所有可用的 LookAndFeel 主题?

java - 如何在 Java 中使用替换来交换反斜杠和双引号的空格

java - 使用 vertx embedded 和 Guice 为 Verticles 设置多个实例

java - 通用 Guice 性能指南

java - Apache-POI 忽略 Excel 工作表的行

java - 解密时得到 "EVP_DecryptFinal_ex:wrong final block length"

dependency-injection - Guice:将对象从已安装的模块注入(inject)到依赖的已安装模块

java - 在不访问应用程序的情况下获取 Dagger 组件