使用DispatchingAndroidInjector的优点是什么?和其他dagger.android类? [英] What are the advantages of using DispatchingAndroidInjector<> and the other dagger.android classes?

查看:333
本文介绍了使用DispatchingAndroidInjector的优点是什么?和其他dagger.android类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Dagger 2设置到我的android项目中。这是我第一次使用此框架,到目前为止一切进展顺利。但是我在您的项目中建立此框架的方式上看到了不同的方法,我想知道哪种方法更好,因为我将两者进行比较,对我来说结果是相同的。

I'm working on setting up Dagger 2 into my android project. It is my first time with this framework and everything goes well so far. But I'm seeing different approaches on the way you can set up this framework in your project and I wonder which one is better, because I compare both and for me the result is kind of the same.

我遵循了该指南: https:/ /github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2

在Internet上搜索时,所有人都使用这种方法。
它使用@Module和@Component定义依赖项。

Searching on Internet all of them use this approach. It use @Module and @Component to define the dependencies.

您的应用程序最终像这样结束:

and your application ends up like this:

public class MyApp extends Application {

    private NetComponent mNetComponent;

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

        // Dagger%COMPONENT_NAME%
        mNetComponent = DaggerNetComponent.builder()
                // list of modules that are part of this component need to be created here too
                .appModule(new AppModule(this)) // This also corresponds to the name of your module: %component_name%Module
                .netModule(new NetModule("https://api.github.com"))
                .build();

        // If a Dagger 2 component does not have any constructor arguments for any of its modules,
        // then we can use .create() as a shortcut instead:
        //  mNetComponent = com.codepath.dagger.components.DaggerNetComponent.create();
    }

    public NetComponent getNetComponent() {
       return mNetComponent;
    }
}

但是我发现了另一种方式(我还没有测试它): https://google.github.io/dagger/android.html
而且使用不同的类和注释看起来完全不同。
它使用类似这样的东西:

But I found another way (I haven't tested it):https://google.github.io/dagger/android.html And It looks like completely different, using different classes and annotations. It uses something like this:

@Subcomponent(modules = ...)
 public interface YourActivitySubcomponent extends AndroidInjector<YourActivity> {
   @Subcomponent.Builder
   public abstract class Builder extends AndroidInjector.Builder<YourActivity> {}
 }

@Module(subcomponents = YourActivitySubcomponent.class)
 abstract class YourActivityModule {
   @Binds
   @IntoMap
   @ActivityKey(YourActivity.class)
   abstract AndroidInjector.Factory<? extends Activity>
       bindYourActivityInjectorFactory(YourActivitySubcomponent.Builder builder);
 }

 @Component(modules = {..., YourActivityModule.class})
 interface YourApplicationComponent {}

public class YourApplication extends Application implements HasDispatchingActivityInjector {
   @Inject DispatchingAndroidInjector<Activity> dispatchingActivityInjector;

   @Override
   public void onCreate() {
     super.onCreate();
     DaggerYourApplicationComponent.create()
         .inject(this);
   }

   @Override
   public DispatchingAndroidInjector<Activity> activityInjector() {
     return dispatchingActivityInjector;
   }
 }

所以,我的问题是:


  1. 哪个更好?

  1. which one is better?

选择一个是什么原因?

What are the reasons for choosing one approach instead of the other?


推荐答案

设置Dagger 2的方法现在已在官方 Dagger 2文档中规定的Android版本具有许多优点,应该首选。优点只是在那里详细说明了,即:

The method of setting up Dagger 2 for Android that is now prescribed in official Dagger 2 documentation has a number of advantages and should be preferred. The advantages are just those elaborated there, namely:



  1. 复制粘贴代码使以后很难重构。随着越来越多的开发人员复制粘贴该块,越来越少的人会知道它的实际作用。

  1. Copy-pasting code makes it hard to refactor later on. As more and more developers copy-paste that block, fewer will know what it actually does.

从根本上说,它要求请求注入的类型(FrombulationActivity)了解其注射器。即使这是通过接口而不是具体类型完成的,它也打破了依赖注入的核心原理:一个类对它的注入方式一无所知。

More fundamentally, it requires the type requesting injection (FrombulationActivity) to know about its injector. Even if this is done through interfaces instead of concrete types, it breaks a core principle of dependency injection: a class shouldn’t know anything about how it isinjected.


让我们将这些原因应用于您的第一个示例。

Let's apply those reasons to your first example.

原因1

假设我们有一个活动想要使用您的 NetComponent 。我们称之为 NetActivity 。该 NetActivity onCreate(Bundle savedInstanceState)方法看起来像这样:

Assume we have an Activity that wants to use your NetComponent. Let's call it NetActivity. The onCreate(Bundle savedInstanceState) method of that NetActivity will look something like this:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ((MyApp) getApplicationContext()).getNetComponent().inject(this);
}

此代码具有散布在燕麦片(不是我的明喻)上的趾甲剪裁的所有视觉吸引力,最终在使用 NetComponent 的所有注入网站活动中复制粘贴。如果您使用更复杂的组件,例如文档中的以下示例:

This code has all the visual appeal of toenail clippings scattered on oatmeal (not my simile) and will end up copy-pasted in all of the injection site Activities where you use NetComponent. If you use more complicated components, such as this example from the docs:

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // DO THIS FIRST. Otherwise frombulator might be null!
  ((SomeApplicationBaseType) getContext().getApplicationContext())
     .getApplicationComponent()
     .newActivityComponentBuilder()
     .activity(this)
     .build()
     .inject(this);
 // ... now you can write the exciting code

}

更糟。它可以轻松地退化为一段神奇的代码,必须在整个注入位置进行复制和粘贴。如果更改了,很容易忘记只更新一个站点并导致应用程序崩溃。

Even worse. It can easily degenerate into a magical piece of code that must be copied and pasted throughout the injection sites. If it changes, it's easy to forget to update just one site and have your app crash.

原因2

依赖项注入的一大优点是注入站点无需了解或关心其注入器,就像依赖项不了解或关心其依赖项一样。返回到我们的 NetActivity ,我们有:

One of the great advantages of dependency injection is injection sites need not know or care about their injectors, just as dependencies do not know or care about their dependents. To return to ourNetActivity, we have:

((MyApp) getApplicationContext()).getNetComponent().inject(this);

活动知道有关其注入器( NetComponent )的信息,现在该活动与一个结果 MyApp 和方法 getNetComponent()。如果这两个类中的任何一个发生更改, NetActivity 也将不得不更改。

The Activity "knows" about its injector (NetComponent), and the Activity is now coupled with a concretion MyApp and the method getNetComponent() from the same. If either of these classes changes, NetActivity will have to change as well.

在Activity中采用新的注入方式的优点和Dagger 2.10及更高版本中可用的片段与这些缺点恰好相反:

The advantages of following the new way of injection inside Activity and Fragments available in Dagger versions 2.10 and forward are just the opposite of these disadvantages:


  1. 您最终得到的复制粘贴代码更少

  2. 请求注射的类型不再需要了解或关心其喷射器或喷射器的来源。

此外,如此博客,相对于依赖组件减少了应用程序的方法数量。

Furthermore, as pointed out in this blog, preferring subcomponents over dependent components reduces the method count of your app.

虽然使用子组件最初看起来更困难,但仍有一些明显的优点。但是,出于学习目的,最初依赖Dagger的组件可能更容易理解。如果第二个示例开始时过于复杂,则可以在精通技巧后逐步过渡到首选方法。

While using subcomponents may initially seem more difficult, there are some clear advantages. However, for the purposes of learning Dagger dependent components may be initially easier to understand. If the second example is too complicated initially, you can graduate to the preferred method when you have gained finesse.

这篇关于使用DispatchingAndroidInjector的优点是什么?和其他dagger.android类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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