8

我正在使用Dagger将依赖项注入到 Android 应用程序中,但我偶然发现了一个我不完全确定如何以干净的方式解决的问题。

我想要实现的是实例化助手并将它们注入我的活动中,并且让这些助手也包含注入的成员。

什么有效

我的助手被注入的活动:

public class MyActivity extends Activity {
    @Inject SampleHelper helper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ((MyApplication) getApplication()).inject(this);

        Log.i("debug", "helper = " + helper);
        Log.i("debug", "helper context = " + helper.context);
    }
}

创建对象图的应用程序:

public class MyApplication extends Application {
    private ObjectGraph graph;

    @Override
    public void onCreate() {
        super.onCreate();

        graph = ObjectGraph.create(getModules());
    }

    private Object[] getModules() {
        return new Object[] { new MyModule(this) };
    }

    public void inject(Object target) {
        graph.inject(target);
    }
}

当我直接实例化一个 SampleHelper 类时,注入工作完美,该类又接收注入的应用程序上下文:

@Singleton
public class SampleHelper {

    @Inject public Context context;

    @Inject
    public SampleHelper() {}
}

使用以下模块:

@Module(
    injects = { MyActivity.class },
    complete = false,
    library = true
)
public class MyModule {
    private final MyApplication application;

    public MyModule(MyApplication application) {
      this.application = application;
    }

    @Provides @Singleton Context provideApplicationContext() {
        return application;
    }
}

什么不起作用

但是,当我将辅助接口与其实现分开时:

public interface SampleHelper {
}

@Singleton
public class SampleHelperImpl implements SampleHelper {

    @Inject public Context context;

    @Inject
    public SampleHelperImpl() {}
}

并将其添加到匕首模块:

public class MyModule {
    ...

    // added this method
    @Provides @Singleton public SampleHelper provideSampleHelper() {
        return new SampleHelperImpl();
    }

    ...
}

正如我所预料的那样,上下文没有被注入到我的 SampleHelperImpl 中。现在,我猜这是由于 SampleHelperImpl 是通过直接构造函数调用而不是注入启动的构造函数调用来实例化的,因为 MyModule#provideApplicationContext() 甚至没有被调用,所以我的猜测是我缺少关于 Dagger 的一些东西(这是可能,因为我之前的 DI 经验只包括 Spring)。

关于如何以“干净的匕首”方式将我的上下文注入到我的注入助手实现中的任何想法?

非常感谢!

4

4 回答 4

18

这是一个相当古老的问题,但我认为您想要的是:

@Provides @Singleton public SampleHelper provideSampleHelper(SampleHelperImpl impl) {
    return impl;
}

这样,Dagger 将创建您的SampleHelperImpl并因此注入它。

于 2013-08-27T00:27:11.780 回答
1

(适用于 Dagger v1.0.1)

确保您使用的是适配器注入。使用反射注入,dagger 显然不会对@Provides对象进行传递注入。我认为这是一个错误。

于 2013-07-23T16:14:28.710 回答
1

如果有人有兴趣,在 dagger 模块中实现 @Provides 方法时,您可以获得像这样的 dagger-handled objects 实例:

@Provides @Singleton public SampleHelper provideSampleHelper(Context context) {
    SampleHelper helper = new SampleHelperImpl();
    helper.setContext(context);
    return helper;
}

这行得通,但我仍然觉得它有点笨拙,因为我必须明确地调用我的助手设置器(通常是你想通过注入摆脱的东西)。

(我会稍等一下,以防有人提出更好的解决方案)

于 2013-07-16T08:14:27.457 回答
0

在注入正确的上下文方面,您可能想看看这个示例https://github.com/square/dagger/tree/master/examples/android-activity-graphs

于 2013-07-16T13:07:22.003 回答