Dagger:android.content.Context上没有可注射成员。你想添加一个注射构造函数吗?模块类所要求的

时间:2014-04-26 22:38:37

标签: java android dependency-injection dagger

我正在尝试将我的单身CookieUtil转换为注入Dagger LoginActivityCookieUtil需要一个应用程序context,因此我设置了以下结构:

AndroidModule

@Module(
        injects = {
            CookieUtil.class,
            LoginActivity.class
        },
        library = true
)
public class AndroidModule {
    private final App application;

    public AndroidModule(App application) {
        this.application = application;
    }

    /**
     * Allow the application context to be injected but require that it be annotated with
     * {@link ForApplication @Annotation} to explicitly differentiate it from an activity context.
     */
    @Provides
    @Singleton
    @ForApplication
    Context provideApplicationContext() {
        return application;
    }

    @Provides
    @Singleton
    CookieUtil provideCookieUtil() {
        return new CookieUtil();
    }
}

CookieUtil(我想注入LoginActivity)

@Singleton
public class CookieUtil {
    @Inject Context mContext; // gets injected with a app context. is this right ?

    private PersistentCookieStore persistentCookieStore;

    private CookieUtil() {
      // use injected mContext
      persistentCookieStore = new PersistentCookieStore(mContext);
      // ...
    }
}

LoginActivity(我想要注入CookieUtil的地方)

公共类LoginActivity扩展了BaseActivity {     @Inject CookieUtil cookieUtil;

@Override
protected void onCreate(Bundle savedInstanceState) {
  // use CookieUtil ...
}

}

我还设置了Dagger示例中的所有bootstraping内容,以使一切工作

BaseActivity

public class BaseActivity extends ActionBarActivity {
    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Perform injection so that when this call returns all dependencies will be available for use.
        ((App) getApplication()).inject(this);
    }
}

应用

public class App extends Application {
  private ObjectGraph graph;

  public void onCreate() {
    super.onCreate();
    graph = ObjectGraph.create(getModules().toArray());
    // ...
  }

  protected List<Object> getModules() {
    return Arrays.asList(
      new AndroidModule(this),
      new CupsModule() // Another module I haven't listed
    );
  }

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

}

ForApplication

@Qualifier
@Retention(RUNTIME)
public @interface ForApplication {
}

当我运行代码时,我得到了

  

android.content.Context上没有可注入的成员。你想加吗?   注射构造函数? CookieUtil for AndroidModule所需的

我做错了什么?

对于我来说,一切看起来仍然很神奇,因为我并不完全了解如何连接所有内容,因此非常感谢详细解释。

另外,如果有人能指出我对匕首模块的解释会有帮助,何时分成两个不同的模块是有意义的?他们通常会绑定什么逻辑部分?

由于

修改

Christian Gruber建议更改

@Singleton
public class CookieUtil {
    private Context mContext;
    private PersistentCookieStore persistentCookieStore;

    @Inject
    public CookieUtil(Context context) {
          // use injected context
          mContext = context
          persistentCookieStore = new PersistentCookieStore(mContext);
          // ...
    }
}

1 个答案:

答案 0 :(得分:3)

Cookie不能拥有私有构造函数,仍然可以由Dagger创建(配置)。你可以拥有一个包友好的构造函数,然后它可以在没有@Provides CookiUtil ...的情况下工作。为您控制的类提供方法并且可以进行注射似乎是浪费。

一般来说,Dagger认为&#34;绑定&#34;根据&#34;键&#34;这是它的类型(具有具体类型参数,例如Foo<Bar>)以及任何@Qualifier。因此Foo<Bar>类型与@ForApplication Foo<Bar>不同。在发生@Inject的任何地方都会请求绑定,并且在@Provides发生的任何地方提供绑定(或者对于非限定绑定,如果类具有@Inject标记的构造函数或字段,则提供隐式绑定对于每个@Inject字段或构造函数参数,必须存在该键的当前绑定.Dagger需要能够看到它用于创建事物的方法,因此通常private字段,方法和构造函数是不可能的。

此外,请不要在没有限定符的情况下注入Context。或者更好的是,如果您指的是Application子类型,请注入ActivityContext。如果您不区分Android调用Context个子类型的30,000件内容,则无法管理您的图表。 (魅)

相关问题