让我说:
public interface Shape {}
public class Rectangle implements Shape {
}
public class Circle implements Shape {
}我有一个ApplicationModule,它需要为Rec和循环提供实例
@Module
public class ApplicationModule {
private Shape rec;
private Shape circle;
public ApplicationModule() {
rec = new Rectangle();
circle= new Circle ();
}
@Provides
public Shape provideRectangle() {
return rec ;
}
@Provides
public Shape provideCircle() {
return circle;
}
}和ApplicationComponent
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
Shape provideRectangle();
}用代码的方式-它不会编译。错误说法
错误:(33,20)错误:形状被多次绑定。
这对我来说是有意义的,因为组件正在试图找到一个Shape实例,并且它找到了其中的两个,所以它不知道返回哪个实例。
我的问题是-我怎么处理这个问题?
发布于 2016-10-10 20:12:25
我最近在这篇文章中给出了这样一个问题的答案:
Dagger 2:获得具有@Named的同一个对象的多个实例时出错
需要在模块中使用@Named("someName"),如下所示:
@Module
public class ApplicationModule {
private Shape rec;
private Shape circle;
public ApplicationModule() {
rec = new Rectangle();
circle= new Circle ();
}
@Provides
@Named("rect")
public Shape provideRectangle() {
return rec ;
}
@Provides
@Named("circle")
public Shape provideCircle() {
return circle;
}}
然后在需要注入它们的地方,只需编写
@Inject
@Named("rect")
Shape objRect;这很有趣,但你必须用另一种方式在科特林注射:
@field:[Inject Named("rect")]
lateinit var objRect: Shape发布于 2016-10-10 17:46:56
@Qualifier注释是区分具有相同类型的不同实例或注入请求的正确方法。主用户指南页面有关于他们的整整一节。
@Qualifier @Retention(RUNTIME)
public interface Parallelogram {} /* name is up to you */
// In your Module:
@Provides @Parallelogram
public Shape provideRectangle() {
return rec ;
}
// In your other injected types:
@Inject @Parallelogram Shape parallelogramShape;
// or
@Inject @Parallelogram Provider<Shape> parallelogramShapeProvider;
// In your Component:
@Parallelogram Shape provideRectangle();旁白:虽然我同意sector11的观点,即您不应该在注入类型中使用new,但如果需要的话,模块正是调用new的正确位置。除了添加限定符注释之外,我认为您的模块对我来说非常合适。
与自定义限定符注释相比,编辑有关@命名的用法的:
@Qualifier注释,很像我上面创建的注释。对于简单的情况,它工作得很好,但是因为绑定只是一个字符串,所以在检测有效的键或自动完成键时,IDE不会提供太多的帮助。@Named和自定义限定符,就像我前面对@Parallelogram所做的那样。发布于 2016-10-10 20:47:10
我不认为在new的构造函数中使用Module运算符是个好主意。这将在初始化对象图时(即调用new ApplicationModule()时)创建每个提供对象的实例,而不是达格尔第一次需要该对象的时候。在这种情况下(只有两个对象),它可以忽略不计,但在较大的项目中,这可能会在应用程序启动时造成瓶颈。相反,我将遵循@sector11 11的建议,并在@Provides注释的方法中实例化您的对象。
至于提供两个相同类型的对象,@Jeff和@Amir都是正确的。可以使用提供的@Named()限定符,也可以创建自己的限定符,如下所示:
@Qualifier @Retention(RetentionPolicy.RUNTIME)
public @interface RectangleShape {}
@Qualifier @Retention(RetentionPolicy.RUNTIME)
public @interface CircleShape {}那么您的ApplicationModule应该如下所示:
@Module
public class ApplicationModule {
@Provides @RectangleShape // @Named("rectangle")
public Shape provideRectangle() {
return new Rectangle();
}
@Provides @CircleShape // @Named("circle")
public Shape provideCircle() {
return new Circle();
}
}这样,就可以将这些对象注入到类中,如下所示:
@Inject @RectangleShape /* @Named("rectangle") */ public Shape mRectangle;
@Inject @CircleShape /* @Named("circle") */ public Shape mCircle;如果需要在不使用Shape注释的情况下提供@Inject类的实例,则可以在Component类中这样做:
@Component(modules = { ApplicationModule.class })
public interface ApplicationComponent {
void inject(MyApplication application);
@RectangleShape // @Named("rectangle")
Shape getRectangle();
@CircleShape // @Named("circle")
Shape getCircle();
}这些方法将提供由@Provides注释的方法提供的每个类的相同实例。
https://stackoverflow.com/questions/39953933
复制相似问题