在Android中"注入一切"是一种不好的做法吗?

Igo*_*dro 3 java android dependency-injection dagger-2

关于依赖注入的研究我发现一些方法建议注入所有东西,而另一些方法则说没有必要这样做.

在我目前的项目中,关于依赖注入的经验法则是" 如果该类是由我创建的,那么我可以将其注入 ".换句话说只有类喜欢SimpleDateFormat,ArrayList,HashMap是在我的项目newables.我的意图这样做的方法是,我可以@Inject任意类的任意一次调用Injector.getApplicationComponent().inject(this)Activity.基本上我的所有类都有一个非args构造函数@Inject.

我主要使用DI,因为我认为一旦newDagger生成的类专门使用运算符,它将改善性能和内存使用.但我读了Dagger 1开发人员的帖子,说DI对性能没有影响,用法基本上是为了减少样板.

第一个问题是:

  • Dagger 2在Android应用程序中没有任何性能优势?

我的项目运行没有问题,我认为"注入一切"的方法有助于更好地组织,尽管有一些缺点.

使用此方法的一个示例是以下类:

public class TimelineEntryAdapter {

@Inject
Provider<TwitterEntry> mTwitterProvider;

@Inject
Provider<InstagramEntry> mInstagramProvider;

@Inject
Provider<FacebookEntry> mFacebookProvider;

@Inject
TimelineEntryComparator mComparator;

@Inject
public TimelineEntryAdapter() {
}
Run Code Online (Sandbox Code Playgroud)

第二个问题是:

  • 在Android中注入所有东西是不好的做法?

如果第二个问题的答案是"否",那么有一种更好的方法来处理非args构造函数来创建类吗?因为当我创建一个带有@Inject注释的非args构造函数并且类需要一些参数来使用时,我必须使用setters:

public class SavelArtist {

private MusicBrainzArtist mMusicBrainzArtist;

private DiscogsArtist mDiscogsArtist;

private List<SavelTweet> mTweetList;

private SpotifyArtist mSpotifyArtist;

private List<SavelInstagram> mInstaTimeline;

private List<SavelFacebook> mFacebookTimeline;

private List<SavelRelease> mReleases;

@Inject
Provider<SavelRelease> mReleaseProvider;

@Inject
public SavelArtist() {
}

public void setMusicBrainzArtist(MusicBrainzArtist mbArtist) {
    mMusicBrainzArtist = mbArtist;
}

public void setDiscogsArtist(DiscogsArtist discogsArtist) {
    mDiscogsArtist = discogsArtist;
}

public void setTweetList(List<SavelTweet> tweetList) {
    mTweetList = tweetList;
}

public void setSpotifyArtist(SpotifyArtist spotifyArtist) {
    mSpotifyArtist = spotifyArtist;
}

public void setInstaTimeline(List<SavelInstagram> instaTimeline) {
    mInstaTimeline = instaTimeline;
}

public void setFacebookTimeline(List<SavelFacebook> fbTimeline) {
    mFacebookTimeline = fbTimeline;
}
Run Code Online (Sandbox Code Playgroud)

一旦所有参数在流程中同时获得,所有参数都可以在构造函数上设置.

Dav*_*son 6

关于依赖注入的研究我发现一些方法建议注入所有东西,而另一些方法则说没有必要这样做.

您引用的froger_mcs博客条目并不主张注入所有内容.它非常明确地指出:

这篇文章的目的是展示我们可以做什么,而不是我们该做什么.

它继续说明注入一切的缺点:

如果您想在项目中使用Dagger 2几乎所有内容,您很快就会看到生成的代码用于注入的64k方法计数限制.

现在,问你的问题:

Dagger 2在Android应用程序中没有任何性能优势?

虽然Dagger 2提供了优于其他基于反射的DI框架(例如Guice)的性能优势,但它并不声称通过调用构造函数来手动构建对象图提供任何性能优势.您可以自己检查生成的类,看看这些确实最终仍然调用构造函数.

在Android中注入所有东西是不好的做法?

好吧,让我们采取以下非常常见的Android代码:

Intent nextActivity = new Intent(this, NextActivity.class);
startActivity(nextActivity);
Run Code Online (Sandbox Code Playgroud)

我们应该IntentFactory使用Dagger 2 提取并注入它,仅仅是为了避免使用new关键字吗?在这一点上,很容易接近迂腐.您引用另一个答案中关于注射剂和新品之间差异的建议更灵活,更优雅.

继续你的下一个问题:

如果第二个问题的答案是"否",那么有一种更好的方法来处理非args构造函数来创建类吗?因为当我用@Inject注释创建一个非args构造函数并且一个类需要一些参数来处理时,我必须使用setter:

使用setter是参数的错误方法.您应该区分依赖项参数.依赖关系通常与对象本身具有相同的生命周期.在对象的生命周期中,可以使用不同的参数调用为该对象公开的方法.