为什么Dagger注入不起作用,但component.getObject是

时间:2015-10-05 11:42:25

标签: java android dependency-injection dagger-2

我正在尝试使用Dagger 2来实例化Retrofit界面。 CloudContactDataStore类注入RestClient并调用其方法。

当我实例化CloudContactDataStore对象时,其RestClient属性的值为null

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
    }
}

以下是我创建Dagger模块和组件的方法:

@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();
    }
}

那么,为什么inject函数不起作用,而是调用component' s getRestClient()是?

1 个答案:

答案 0 :(得分:1)

我发现查看Dagger 2生成的代码非常有用,因为它很容易理解,并且通常可以指向正确的方向。

Dagger 2创建的代码与您的代码非常相似,因此请考虑如何实现ApiComponent.inject(ContactDataStore)。假设在该方法中您可以访问RestClient,您将如何进入该字段?如果你坐下来写下来,你会注意到你必须做这样的事情:

((CloudContactDataStore) contactDataStore).restClient = restClient;

或者换句话说,您需要将其转换为特定的实现。匕首2不会被击倒,因为这通常是不安全的。(/至少我还没有看到它)。

所以,你有两个选择。将inject(ContactDataStore)方法更改为inject(CloudContactDataStore),或在ContactDataStore上提供允许传递RestClient的方法。

更新:通过抽象即接口方法无法实现@Inject。

如果你想通过ContactDataStore API注入它,那么你就会遇到问题,因为目前Dagger 2中有一个限制(已经提出删除它的功能请求),你不能用{标记一个抽象方法{1}}。所以,在此期间(或者永远,如果有一些原因导致它无法在Dagger 2中工作),您需要手动完成,即从组件方法中获取@Inject的实例并将其传递给适当的方法在界面上。