Android上的Dagger 2。存储和访问@Singleton组件的不同方法 [英] Dagger 2 on Android. Different ways to store and access a @Singleton Component

查看:57
本文介绍了Android上的Dagger 2。存储和访问@Singleton组件的不同方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是关于如何存储@Singleton作用域的Dagger 2组件的第N个问题,其寿命应等于应用程序的寿命。

This is the Nth question about how to store @Singleton scoped Dagger 2 Components whose lifetime should equal the application's lifetime.

在使用Dagger 2的Android应用程序中,通常存在至少有一个@Singleton作用域的组件,该组件应在应用程序的整个生命周期中持续有效:由于这些要求,通常将其初始化并存储在自定义Application类中。

In Android apps using Dagger 2 there is usually at least one Component which is @Singleton scoped and should last for all the application's lifetime: because of these requirements it is usually initialised and stored inside a custom Application class.

该组件的实例在我们应用程序的所有部分中都必须是可访问的,我见过这样的代码:

Since the instance of this Component must be reachable in all parts of our Application I've seen code like this:

public class App extends Application {

    public static AppComponent appComponent;

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

        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this)).build();
    }
}

这样可以在其他任何地方访问

App.appComponent.inject(this);



2。将组件存储在应用程序实例内部的私有变量中,并为其创建静态访问器。



2. Store the component in a private variable inside the application instance and create a static accessor for it.

public class App extends Application {

    private static AppComponent appComponent;

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

        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this)).build();
    }

    public static AppComponent getAppComponent() {
        return appComponent;
    }
}

这样可以在其他任何地方访问与:

App.getAppComponent().inject(this);



3。将组件存储在应用程序实例内部的私有变量中,并为其创建一个非静态访问器。



3. Store the component in a private variable inside the application instance and create a non static accessor for it.

public class App extends Application {

    private AppComponent appComponent;

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

        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this)).build();
    }

    public AppComponent getAppComponent() {
        return appComponent;
    }
}

这种方式只能从拥有对上下文的引用的class实例:

// From within an Activity.
((App) getApplication()).getAppComponent().inject(this);

// From within a Fragment.
((App) getActivity().getApplication()).getAppComponent().inject(this);

// From within any other class which holds a reference to a Context. 
((App) context.getApplicationContext()).getAppComponent().inject(this);

最后一种方法使得必须将Context引用传递给愿意访问Component的任何类(即使该类出于任何其他目的不需要该Context)。

This last way makes it pretty much compulsory to pass a Context reference to any class willing to access the Component (even if that Context isn't needed by that class for any other purposes).

恕我直言,IMHO不得不手动注入 Context实例只是为了访问注入器本身的声音

IMHO having to "manually inject" a Context instance only to access the injector itself sounds a bit counter intuitive.

另一方面,许多人建议不要使用静态变量,但是:为什么呢?如果对象必须在应用程序的生存期内(这意味着JVM实例的整个生存期)都保留在内存中,那么将其存储在静态变量中又有什么问题呢?

On the other side many advise against using static variables but: why? If an object must stay in memory for the application's lifetime (which means for the whole lifetime of the JVM instance) what's the problem if it's stored in a static variable?

Others说静态的东西不能在测试中被模拟,这是真的,尽管我不确定我完全明白了这一点,因为它是DI模式,可以轻松进行模拟/测试,而不是注入器本身,所以我们为什么要模拟喷油器本身?

Others say that static stuff can't be mocked in tests and it's true, though I'm not sure I totally get this because it is the DI pattern which enables easy mocking/testing and not the injector itself, so why would we want to mock the injector itself?

这些替代方案的优缺点是什么?除了这里已经提到的以外,还有其他可能的选择吗?

What are the pros and cons of these alternatives? Are there any other possible alternatives besides the ones already mentioned here?

推荐答案

对于1和2,您正在使用静态引用。这是关于为什么要避免使用它们的好话题

With 1 and 2 you are using static references. This is a good thread about why to avoid them

Why are static variables considered evil?

所以剩下的唯一选择是第3个。那就是我在项目中使用的。
关于是否应该将上下文作为参数传递,取决于项目的体系结构以及Dagger依赖项的设计方式。就个人而言,我没有这个问题,因为我只注入了活动/片段。您能否举个例子,说明您需要传递上下文以注入依赖项?

So the only option left is the 3rd. That is what I am using on my projects. About if you should pass the context as argument or not, depends on the architecture of your project and how you designed the Dagger dependencies. Personally I don't have that problem because I am only injecting in Activities/Fragments. Can you give me an example where you need to pass the context to inject dependencies?

这篇关于Android上的Dagger 2。存储和访问@Singleton组件的不同方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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