1

我正在“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)。


编辑:对不起,伙计们,我的示例代码中有一个错误,但我会保持原样,因为它对于理解下面 Christian 的回答很有用。

4

1 回答 1

3

实际上,您的示例代码中有一个错误。您没有可注入的构造函数 - 您不能注入实例方法,只能注入构造函数,并且永远不会调用该方法。

你应该有:

public class XmlDataReader implements DataReader<XmlPushable> {

  protected final XmlPullParser mXmlPullParser;

  @Inject
  public XmlDataReader(XmlPullParser xmlPullParser) {
      mXmlPullParser = xmlPullParser;
  }
}

这样它就是一个构造函数,并且会被正确注入。

至于整体方法,您的方向是正确的。您,并在您的提供方法中@Provide DataReader<XmlPushable有效地绑定到它。XmlDataReader到现在为止还挺好。Dagger 在被要求时DataReader<XmlPushable>将使用该绑定,并将有效地传递依赖项并提供XmlDataReader来满足这一点。

XmlDataReader有一个带@Inject注释的构造函数,因此 Dagger 的分析会将其视为“可注入类型”,因此您不需要@Provides提供它。只要您有一个XmlPullParser具有带@Inject注释的构造函数或在@Provides模块上的方法中提供的,您在此处编码的内容似乎不错,但还不够完整。

您的@Module 中没有列出任何入口点,并且您必须有一个类,该类将是您从 ObjectGraph 获得的第一件事。所以这段代码是合理的,但不完整。您需要注入的东西(通过字段或构造函数)DataReader<XmlPushable> 例如,您可能会做一个FooActivitywhich 来执行此操作。

考虑:

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'inject(Object)方法,这会导致 Dagger 注入任何带@Inject注释的字段。这些字段是DataReader<XmlPushable>由 XmlDataReader 满足的字段,它由 XmlPullParser 提供,而 XmlPullParser 是通过使用 XmlPullParser 提供的。这一切都沿着依赖链向下流动。

小注 -@Module(complete=true)是默认值。您不需要指定完整,除非它不完整并且您指定false

于 2013-02-13T05:23:02.940 回答