我正在尝试使用工厂在运行时注入一个类来将枚举映射到类类型,但是我遇到了一个问题,当我尝试注入它时会抛出错误。
java.lang.IllegalArgumentException: No inject registered for members/com.example.android.push.DefaultPushHandlerStrategy. You must explicitly add it to the 'injects' option in one of your modules.
public class PushFactory {
private Map<PushType, Class<? extends PushHandlerStrategy>> classMap = new HashMap<PushType, Class<? extends PushHandlerStrategy>>();
@Inject
public PushFactory() {
classMap.put(PushType.DEFAULT, DefaultPushHandlerStrategy.class);
classMap.put(PushType.VIDEOS, VideosPushHandlerStrategy.class);
classMap.put(PushType.MESSAGE, MessagePushHandlerStrategy.class);
}
public PushHandlerStrategy getPushHandlerStategy(PushType type){
Class<? extends PushHandlerStrategy> klazz = classMap.get(type);
if(klazz == null){
klazz = DefaultPushHandlerStrategy.class;
}
ObjectGraph graph = App.getApplication().getObjectGraph();
return graph.get(klazz); // this line throws the exception
}
}
基本上,我想要实现的是基于GCM推送中的一些数据实例化策略。
我在模块中注册了以下内容。
@Module(
injects = {
PushFactory.class,
PushBroadcastReceiver.class
},
complete = false,
library = false
)
public class PushModule {
}
任何想法我的方法有什么问题?
编辑:
我能够通过注入提供商实现我想要的,但似乎有点麻烦。有什么方法吗?
public class PushFactory {
private Map<PushType, Provider<? extends PushHandlerStrategy>> providerMap = new HashMap<PushType, Provider<? extends PushHandlerStrategy>>();
@Inject
public PushFactory(Provider<DefaultPushHandlerStrategy> d, Provider<VideosPushHandlerStrategy> v, Provider<MessagePushHandlerStrategy> m) {
providerMap.put(PushType.DEFAULT, d);
providerMap.put(PushType.VIDEOS, v);
providerMap.put(PushType.MESSAGE, m);
}
public PushHandlerStrategy getPushHandlerStrategy(PushType type){
Provider<? extends PushHandlerStrategy> provider = providerMap.get(type);
if(provider == null){
provider = providerMap.get(PushType.DEFAULT);
}
return provider.get();
}
}
答案 0 :(得分:1)
您的原始解决方案应该是可以实现的,但似乎您可能错过了PushModule中这些类的注入定义。由于您是直接使用objectGraph.get(class)而不是通过字段或构造函数注入创建这些对象,因此不将这些类添加到注入中Dagger无法知道这些类是否需要,并且不会为它们创建任何管道,因此会失败在运行时。
@Module(
injects = {
PushFactory.class,
PushBroadcastReceiver.class,
DefaultPushHandlerStrategy.class,
VideosPushHandlerStrategy.class,
MessagePushHandlerStrategy.class
},
complete = false,
library = false
)
public class PushModule {
}