将基于 Guice 的项目迁移到 Dagger
Migrating a Guice-based project to Dagger
我有一个使用 vanilla Guice 的基于 Guice 的项目;
没有 Assisted-Inject,没有 AOP,没有扩展 Guice 的额外插件,等等。
为了 运行 它更容易上 Android,Dagger 似乎是一个更好的解决方案。
每个 class 都有一个依赖项和一个带有 @Inject
注释的构造函数。
没有使用字段或方法注入。
这些模块非常简单(使 Guice 变得矫枉过正)并且大部分包含如下绑定:
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 模块。
@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();
}
}
它将绑定到“Injector
”(组件):
@Component(modules={SomethingModule.class})
//scope if needed
public interface SomethingComponent {
@Named("something")
Handler handler();
void inject(ThatThingy thatThingy);
}
这是您必须使用 APT 生成的构建器创建的 "injector":
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
有 一个 "injector"(组件)。作用域可以通过子组件和组件依赖来实现。
重要的是,组件具有提供方法(如果您使用组件依赖项,它们是继承到子范围组件的依赖项)和 void inject(X x);
格式化方法。这是字段注入所必需的 每个具体类型 。例如,一个基础class只能注入自身,而不能其子class。但是,您可以编写一个名为 protected abstract void injectThis()
的方法,该方法也会在 subclass 上调用 .inject(this)
。
由于我还没有真正使用过 Guice,所以我不确定我是否遗漏了什么。我想我忘记了构造函数注入,这是一个问题,因为虽然 Dagger 确实支持它,但它无法重新配置。对于重新配置,您必须使用模块,并自己在构造函数中进行注入。
@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();
}
我有一个使用 vanilla Guice 的基于 Guice 的项目;
没有 Assisted-Inject,没有 AOP,没有扩展 Guice 的额外插件,等等。
为了 运行 它更容易上 Android,Dagger 似乎是一个更好的解决方案。
每个 class 都有一个依赖项和一个带有 @Inject
注释的构造函数。
没有使用字段或方法注入。
这些模块非常简单(使 Guice 变得矫枉过正)并且大部分包含如下绑定:
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 模块。
@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();
}
}
它将绑定到“Injector
”(组件):
@Component(modules={SomethingModule.class})
//scope if needed
public interface SomethingComponent {
@Named("something")
Handler handler();
void inject(ThatThingy thatThingy);
}
这是您必须使用 APT 生成的构建器创建的 "injector":
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
有 一个 "injector"(组件)。作用域可以通过子组件和组件依赖来实现。
重要的是,组件具有提供方法(如果您使用组件依赖项,它们是继承到子范围组件的依赖项)和 void inject(X x);
格式化方法。这是字段注入所必需的 每个具体类型 。例如,一个基础class只能注入自身,而不能其子class。但是,您可以编写一个名为 protected abstract void injectThis()
的方法,该方法也会在 subclass 上调用 .inject(this)
。
由于我还没有真正使用过 Guice,所以我不确定我是否遗漏了什么。我想我忘记了构造函数注入,这是一个问题,因为虽然 Dagger 确实支持它,但它无法重新配置。对于重新配置,您必须使用模块,并自己在构造函数中进行注入。
@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();
}