为什么匕首注射不工作,但component.getObject是 [英] Why Dagger inject is not working but component.getObject yes

查看:179
本文介绍了为什么匕首注射不工作,但component.getObject是的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用匕首2实例化改造接口。在 CloudContactDataStore 类的注入 RESTClient实现并调用它的方法。

I am trying to use Dagger 2 for instantiating a Retrofit interface. The CloudContactDataStore class injects the RestClient and calls its methods.

当我实例化一个 CloudContactDataStore 对象,其 RESTClient实现属性有值。

When I instantiate a CloudContactDataStore object, its RestClient attribute has null value.

public class CloudContactDataStore implements ContactDataStore {

    @Inject RestClient restClient;

    public CloudContactDataStore() {
        this.initializeInjector();
    }

    private void initializeInjector() {
        ApiComponent component = DaggerApiComponent.builder()
            .apiModule(new ApiModule())
            .build();

        component.inject(this); // Nothing changes, restClient is null!

        this.restClient = component.getRestClient(); // This works
    }
}

下面是我如何创建匕首模块和组件:

Here is how I create the Dagger Module and Component:

@Singleton
@Component(modules = ApiModule.class)
public interface ApiComponent {
    void inject(ContactDataStore contactDataStore);

    RestClient getRestClient();
}

@Module
public class ApiModule {

    @Provides public RestClient provideRestClient(ApiService apiService) {
        return new RestClientImpl(apiService);
    }

    @Provides public ApiService provideApiService(RestAdapter restAdapter) {
        return restAdapter.create(ApiService.class);
    }

    @Provides public RestAdapter provideRestAdapter() {
        return RestApiAdapter.getInstance();
    }
}

那么,为什么功能不工作,但调用组件 getRestClient ()是?

So, why the inject function does not work but calling component's getRestClient() yes?

推荐答案

我觉得这是非常有用的看code那匕首2生成,因为它是很容易跟踪和经常可以指向您在正确的方向。

I find it's very useful to look at the code that Dagger 2 generates as it's quite easy to follow and can often point you in the right direction.

2匕首创建code很像你写了这么想想你将如何实施 ApiComponent.inject(ContactDataStore)。假设方法你有机会访问一个RESTClient实现你会怎么让它进入内场?如果你坐下来,写了你会发现,你必须做这样的事情:

Dagger 2 creates code much like you'd write so think about how you would implement ApiComponent.inject(ContactDataStore). Assuming within that method you had access to a RestClient how would you get it into the field? If you sat and wrote it you'd notice that you have to do something like this:

((CloudContactDataStore) contactDataStore).restClient = restClient;

或者换句话说你需要投下来到了具体的实施。匕首2不投下去,永远的(至少我从来没见过吧),因为这通常是不安全的。

Or in other words you'd need to cast it down to a specific implementation. Dagger 2 doesn't cast down, EVER (at least I've not seen it), because that is usually unsafe.

所以,你有两个选择。更改注入(ContactDataStore)方法注入(CloudContactDataStore),或提供有关的方法ContactDataStore 允许 RESTClient实现中进行传递。

So, you have two choices. Change the inject(ContactDataStore) method to inject(CloudContactDataStore), or provide a method on ContactDataStore that allows the RestClient to be passed in.

更新:它不可能通过抽象的,即接口@注入,方法

Update: Its not possible to @Inject through abstract, i.e. interface, method.

如果您想通过 ContactDataStore API注入,那么你有一个问题,因为目前的匕首2的限制(有凸起功能要求将其删除)你不能用标记 @Inject 的抽象方法。因此,在此期间(或永远如果有某种原因,为什么它不能在匕首2工作),你需要做手工,即从获得 RESTClient实现的实例您组件的方法,并把它传递给该接口上的适当的方法。

If you want to inject it through the ContactDataStore API then you have a problem as there is currently a restriction in Dagger 2 (have raised a feature request to remove it) that you cannot mark an abstract method with @Inject. So, in the meantime (or forever if there is some reason why it cannot work in Dagger 2) you will need to do it manually, i.e. get the instance of RestClient from your component method and pass it to the appropriate method on the interface.

这篇关于为什么匕首注射不工作,但component.getObject是的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆