void注入(活动活动)和SomeComponent getSomeComponent()之间的区别

时间:2017-01-25 05:19:10

标签: android dagger-2

通常在使用Dagger 2和android时我有以下内容:

@Singleton 
@Component(modules = {ApplicationModule.class}) 
public interface ApplicationComponent { 
    SharedPreferences getSharedPreferences(); 
}

public class MainActivity extends Activity { 
    SharedPreferences mSharedPrefs; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        mSharedPrefs = ((DemoApplication) getApplication())
                .getComponent().getSharedPreferences();
    } 
}

但最近我看到了这个:

/Folder B 
    file.docx
    fileB.docx
    fileC.docx
    pythonDeleteScript.py
    folderA/
    folderB/
    folderC/
    folderD/

我省略了DemoApplication类和Module类,它们是标准的。

这两种方法有什么区别?亲们的亲和?也许是对还是错?

2 个答案:

答案 0 :(得分:2)

软件工程的dependency inversion principle表明我们应该尝试依赖于抽象而不是结核。

出于这个原因,您应该更喜欢在Activity中进行字段注入的@Inject注释(摘要),而不是从Dagger组件(具体)调用提供方法。

为什么呢?您会注意到@Inject注释是javax.inject包的一部分。这是作为JSR330的一部分引入Java的依赖注入API的标准。还有其他DI框架,例如Guice和Toothpick,可以使用这些注释。如果您将来必须切换DI框架,那么使用@Inject注释会更容易。是的,确实需要更改DI框架。 Roboguice是最近退休的流行DI框架的示例。

为了说明这一点,让我们进行您的Activity,添加一些依赖项,并提取一个注入方法,如下所示:

public class MainActivity extends Activity { 
    @Inject SharedPreferences mSharedPrefs; 
    @Inject Foo foo;
    @Inject Bar bar;

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
    } 

    @VisibleForTesting
    protected void injectMembers() {
        ((DemoApplication) getApplication())
            .getComponent()
            .inject(this); 
    }
}

出现狂野(新)DI框架!您现在必须更改您的应用程序才能快速使用它!你使用JSR330。它非常有效! (翻译:您可以重复使用JSR330 @Inject注释,因为新的DI框架支持它们)。如果您已经更改为类似Guice的新框架,那么您需要做的就是重写您的方法:

    @VisibleForTesting
    protected void injectMembers() {
        GuiceLikeInjector.getInjector(this).injectMembers();  
    }

相反,如果您使用.getSharedPreferences()getFoo()手动注入了这些字段,那么它不是很有效 - 您必须更改许多代码行。

答案 1 :(得分:1)

如果您查看Component生成的代码,您会注意到它通过使用您传递的活动参考直接设置注入字段来实现inject(MainActivity)方法。 所以两个选项都做同样的事情。

我更喜欢第一种方法有两个主要原因。首先,当它们被注释时,注入字段会更加清晰,其次,它使代码更加清晰。在这个示例中,您给了注入一个字段并且更难以看到好处,但是我认为当您需要注入10个字段时,它们将变得更加明显,您必须在{}中分配所有字段{1}},并在组件中为它们声明getter。