Jay*_*dri 46 java android dagger-2
假设我有一个类Util,它接受一个对象 - 类Validator的一个实例.
因为我想避免在Util中实例化Validator类,所以我通过构造函数传递它:
public class Util {
@Inject
public Util(Validator validator) {
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个提供Validator实例的模块:
@Provides
@Singleton
Validator provideValidator() {
return Validator.getInstance();
}
Run Code Online (Sandbox Code Playgroud)
和Util类的一个实例:
@Provides
Util provideUtil(Validator validator) {
return new Util(validator);
}
Run Code Online (Sandbox Code Playgroud)
我有一个组件连线,它会给我一个Util的实例:
Util getUtil()
Run Code Online (Sandbox Code Playgroud)
所以在我的活动中,我可以称之为:
Util myUtil = getComponent.getUtil();
Run Code Online (Sandbox Code Playgroud)
所有这些都可以正常工作 - myUtil在实例化时有一个适当的Validator类实例.
现在我想传入一个名为address的String变量(通过UI输入用户).我想更改构造函数,所以我传入Validator的实例和用户输入的String:
@Inject
public Util(Validator validator, String address) {
}
Run Code Online (Sandbox Code Playgroud)
我无法理解如何传递第二个参数.谁能告诉我怎么样?
理想情况下,我想实例化Util,如:
Util myUtil = getComponent.getUtil(txtAddress.getText());
Run Code Online (Sandbox Code Playgroud)
Sem*_*oor 87
几周前,当我开始研究Dagger 2时,我遇到了同样的问题.我发现有关此信息(以及大多数其他Dagger 2相关问题)的信息很难找到,所以我希望这会有所帮助!
最基本的答案是你不能.您正在寻找的是被称为辅助注入的东西,它不是Dagger 2的一部分.其他一些依赖注入(DI)框架(例如Guice)确实提供了这个功能,因此您可以查看这些.当然,仍然有办法使用Dagger 2做你想做的事情.
与DI结合使用的标准方法是使用Factory模式.基本上,您创建一个可注入的工厂类,它接受运行时参数,例如address
它提供的对象创建方法的参数.
在你的情况,你需要一个UtilFactory
成匕首2注入一个Validator
在instantation和它提供了一个方法create(String address)
创建的实例Util
.UtilFactory
应该保持对注入的实例的引用,Validator
以便它具有Util
在create
方法中创建实例所需的一切.
许多此类工厂的拧密码可能很麻烦.你一定要看看AutoFactory,这可以减轻一些负担.Guice的辅助注射似乎与Dagger 2 + AutoFactory非常相似(尽管具有更好的语法糖).
我怀疑这是你想在这种情况下做的事情,但你可以创建一个提供地址的模块(并实例化一个新的组件).您不必为每个可能的地址创建新的@Module类.相反,您可以将地址作为参数传递给模块的构造函数.您可以使用teano建议的@BindsInstance-annotation来获得类似的结果.
我不确定这是否是反模式.对我来说,在某些情况下,这似乎是一种可接受的路径,但只有当您实际使用相同的地址来初始化"许多"对象时.您绝对不希望为每个需要注入的对象实例化一个新组件和一个新模型.它效率不高,如果你不小心,你会得到比没有Dagger更多的样板代码.
一些了解DI框架时,这是对我非常有用的是,使用DI框架并实现并不意味着你必须要DI初始化所有的对象.根据经验:在编译时注入你知道的并且与其他对象有静态关系的对象; 不要注入运行时信息.
我认为这是一个很好的帖子.它引入了"新产品"和"注射剂"的概念.
Integer
,Address
等是newables的例子.从广义上讲,newables是被动对象,注入或嘲弄它们是没有意义的.它们通常包含应用程序中的"数据",并且仅在运行时可用(例如,您的地址).Newables不应该保留对注射剂的引用,反之亦然(该帖子的作者称之为"可注射/可新生 - 分离").
实际上,我发现在注射剂和新药之间做出明确区分并不总是容易或可能的.尽管如此,我认为它们是很好的概念,可以用作思考过程的一部分.在为您的项目添加另一个工厂之前一定要三思而后行!
在你的情况下,我认为将Util
注射剂和地址视为新产品是有意义的.这意味着该地址不应该是Util
该类的一部分.如果要使用Util
例如验证/ ...地址的实例,只需将要验证的地址作为参数传递给validation/...方法.
tea*_*ano 11
您可以更改组件构建器以注入实例.请参阅:https://google.github.io/dagger/users-guide#binding-instances
在您的情况下,您可以致电:
Util myUtil = DaggerMyComponent.builder().withAddress(txtAddress.getText()).build().getComponent().getUtil();
Run Code Online (Sandbox Code Playgroud)
如果MyComponent定义为:
@Component(modules = UtilModule.class)
interface MyComponent{
MyComponent getComponent();
@Component.Builder
interface Builder {
@BindsInstance Builder withAddress(@Address String address); //bind address instance
MyComponent build();
}
}
Run Code Online (Sandbox Code Playgroud)
和UtilModule:
@Module
class UtilModule{
@Provides
Util getUtil(Validator validator, @Address String address){ //inject address instance
return new Util(validator, address);
}
}
Run Code Online (Sandbox Code Playgroud)
必须在传递给@Component注释中的MyComponent模块的模块类中为Validator提供@Inject注释构造函数或@Provides注释方法.
归档时间: |
|
查看次数: |
16337 次 |
最近记录: |