我是" Daggering"我的Android应用程序和我面临一个小问题,我不知道它是我或框架的错。如果是我,我会对自己感到非常失望:)。
我有以下课程提供:
@Singleton
public class XmlService {
private final DataCommitter<XmlWritable> mXmlCommitter;
private final DataReader<XmlPushable> mXmlReader;
private final ConcurrentObjectMonitor mConcObjMonitor;
@Inject
public XmlService(DataCommitter<XmlWritable> xmlCommitter,
DataReader<XmlPushable> xmlProvider,
ConcurrentObjectMonitor concObjMonitor) {
mXmlCommitter = xmlCommitter;
mXmlReader = xmlProvider;
mConcObjMonitor = concObjMonitor;
}
使用以下(以及其他)类:
public class XmlDataReader implements DataReader<XmlPushable> {
// No Singleton no more.
// Eager Singleton (Therefore it should be made thread safe)
//static XmlDataReader mInstance = new XmlDataReader();
[CUT]
protected XmlPullParser mXmlPullParser;
@Inject
public void XmlDataRead(XmlPullParser xmlPullParser) {
mXmlPullParser = xmlPullParser;
}
这个类在我的XmlServiceModule中引用如下:
@Module(complete = true)
public class XmlServiceModule {
@Provides DataReader<XmlPushable> provideDataReader(XmlDataReader dataReader) {
return dataReader;
}
}
现在,问题是,注入提供的课程是否合法?因为我在XmlDataReader ctor上遇到@Inject错误:无法注入public void XmlDataRead(org.xmlpull.v1.XmlPullParser)。
答案 0 :(得分:3)
实际上,您的示例代码中存在错误。您没有可注入的构造函数 - 您不能注入实例方法,只能注入构造函数,并且永远不会调用该方法。
你应该:
public class XmlDataReader implements DataReader<XmlPushable> {
protected final XmlPullParser mXmlPullParser;
@Inject
public XmlDataReader(XmlPullParser xmlPullParser) {
mXmlPullParser = xmlPullParser;
}
}
这样它就是一个构造函数,并且会被正确地注入。
至于整体方法,你的方向是正确的。您@Provide
DataReader<XmlPushable
,并在您的提供方法中有效地将XmlDataReader
绑定到它。到现在为止还挺好。当被要求DataReader<XmlPushable>
时,Dagger将使用该绑定,并将有效地传递依赖关系,并提供XmlDataReader
来满足此要求。
XmlDataReader
有一个@Inject
带注释的构造函数,因此Dagger的分析会将其视为“可注入类型”,因此您不需要@Provides
来提供它。只要你有XmlPullParser
要么有@Inject
带注释的构造函数,要么在模块的@Provides
方法中提供,那么你在这里编写的代码看起来不错,但不是非常完整。
您的@Module中没有列出任何entryPoints,并且 必须 有一个类,它将是您从ObjectGraph获得的第一个类。所以这段代码尽可能合理,但不完整。你需要注入的东西(通过字段或构造函数)DataReader<XmlPushable>
例如,你可以创建一个FooActivity
来执行此操作。
考虑:
public class XmlDataReader implements DataReader<XmlPushable> {
protected XmlPullParser mXmlPullParser;
@Inject public XmlDataReader(XmlPullParser xmlPullParser) {
mXmlPullParser = xmlPullParser;
}
}
@Module(entryPoints = { FooActivity.class, BarActivity.class })
public class XmlServiceModule {
@Provides DataReader<XmlPushable> provideDataReader(XmlDataReader dataReader) {
return dataReader;
}
@Singleton
@Provides XmlPullParserFactory parserFactory() {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
return factory;
}
@Provides XmlPullParser parser(XmlPullParserFactory factory) {
XmlPullParser xpp = factory.newPullParser();
}
}
public class YourApp extends Application {
private ObjectGraph graph;
@Override public void onCreate() {
super.onCreate();
graph = ObjectGraph.get(new ExampleModule(this));
}
public ObjectGraph graph() {
return objectGraph;
}
}
public abstract class BaseActivity extends Activity {
@Override protected void onCreate(Bundle state) {
super.onCreate(state);
((YourApp) getApplication()).objectGraph().inject(this);
}
}
class FooActivity extends BaseActivity {
@Inject DataReader<XmlPushable> reader;
@Override public void onCreate(Bundle bundle) {
super.onCreate(bundle);
// custom Foo setup
}
}
class BarActivity extends BaseActivity {
@Inject DataReader<XmlPushable> reader;
@Override public void onCreate(Bundle bundle) {
super.onCreate(bundle);
// custom Bar setup
}
}
这可能接近你想要的。所有东西都可以从入口点到达,所有你依赖的东西都是绑定的。这两个活动是您的“入口点”(对象图中的根)。初始化后,他们最终会自行调用ObjectGraph
的{{1}}方法,这会导致Dagger注入任何inject(Object)
个带注释的字段。这些字段是@Inject
字段,它由XmlDataReader满足,XmlDataReader由XmlPullParser提供,XmlPullParser是使用XmlPullParser提供的。这一切都沿着依赖链流动。
小注 - DataReader<XmlPushable>
是默认值。您不需要指定完整,除非它不完整并指定@Module(complete=true)