如何使用像Dagger 2这样的IOC容器注入抽象

时间:2016-12-16 00:13:00

标签: android dependency-injection retrofit retrofit2 dagger-2

我想要做的是抽象,并将抽象作为参数传递。因此,如果有一天出现比改造更好的东西并且我想要切换它,那么这样做很容易。虽然我不知道怎么做。以下是我想要做的基本概述:

public interface ApiClient{
    Object getClient()
}

public class RetrofitClient implements ApiClient{
    private static Retrofit retrofit = null;

    @Override
    public Retrofit getClient(){
        if(retrofit == null){
            OkHttpClient tokenInterceptor = new OkHttpClient.Builder()
                  .addInterceptor(new NetworkInterceptor())
                  .build();

            retrofit = new Retrofit.Builder()
                  .baseUrl("www.hello.com")
                  .addConverterFactory(GsonConverterFactory.create())
                  .build();
        }
    }
}

然后我想通过传递ApiClient作为参数来消费它:

public class MyClass{
    private ApiClient apiClient;

    public MyClass(ApiClient apiClient){
        this.apiClient =  apiClient;
    }

    public void getSomeData(){
        MyClient client = this.client.create(MyClient.class);
    }
}

我需要一些方法将RetrofitClient注入MyClass。 请建议一个IOC容器,任何其他替代方案以及我将如何使用它来实现这一目标,谢谢。

此链接提供了更深入的描述,使用C#和Castle Windsor https://github.com/castleproject/Windsor/blob/master/docs/basic-tutorial.md

1 个答案:

答案 0 :(得分:0)

在Java中,与在C#中一样,抽象由接口或抽象类表示。

您提出的建议可称为“在接口中包装外部库以允许按配置进行交换”。要做到这一点,你必须检查你想要换出的具体化所暴露的方法,并创建一个与之匹配的新接口。

例如,如果外部库具有以下方法:

public class ExternalLibrary {
    void foo() {
        //foo implementation
    }

    void bar() {
        //bar implementation
    }
}

您将创建一个包装器接口:

public interface FooBarable {
    void foo();
    void bar();
}

下一步是让您应用中ExternalLibrary的消费者取决于FooBarable

public class MyActivity extends Activity {

    FooBar fooBar;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DaggerFooBarComponent
            .builder()
            .fooBarModule(new ExternalLibraryModule())
            .build()
            .inject(this);
    }
}

如果您需要为测试模拟交换ExternalLibrary,则可以按照Dagger 2 User Guide中的测试说明使用测试组件:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DaggerTestFooBarComponent
            .builder()
            .mockFooBarModule(new MockFooBarableModule())
            .build()
            .inject(this);
    }

要了解DI框架/ IOC容器Dagger 2如何处理所有这些,您必须查看user guideGoogle Dagger 2 Android app blueprint,因为在上下文中有太多要解释的内容。一个答案。