使用范围时依赖注入的顺序

时间:2016-08-10 21:14:09

标签: android dependency-injection dagger-2

我正在试图找出Dagger 2.我正在尝试设置4个范围:App,User,Activity,Fragment。用户和活动组件是App的子组件。 Fragment是一个以Activity为依赖的Component。

假设我的UserSettingsActivity需要工具栏(由ActivityModule提供)和UserProfile(由UserModule提供)。在我从数据库中请求之前,我不会获得UserProfile,而工具栏可以立即提供。因此,发生的注入顺序首先是ActivityComponent,然后是UserComponent。我有2个@Inject字段,一个用于工具栏,另一个用于活动中的UserProfile。我希望匕首知道依赖关系来自不同的模块,但似乎抱怨在注入ActivityComponent时无法提供UserProfile。显然它不能由ActivityModule提供,但为什么不通过UserModule提供UserProfile的连接?

2 个答案:

答案 0 :(得分:4)

据我所知,Dagger-2不支持"部分注射"。

因此,当您致电myComponent.inject(this)时,如果myComponent无法提供@Inject的所有this注释成员,则Dagger-2会引发错误。

我看到两种解决此限制的方法:

  1. @Inject移除UserProfile注释,通过UserProfile中的公共方法公开UserComponent,并在准备好使用UserComponent时手动注入userProfile = userComponent.getUserProfile()。与此类似的东西:UserComponent
  2. 不要让UserComponent依赖于数据提取。 Toolbar可用于同时注入UserProfileProvider和某些UserProfile,并且当UserProfileProvider可用时,您将从Activity获取Fragment
  3. 我个人认为第二种方法是更好的选择。应该使用DI库以满足对象的需要。施工时的依赖关系。在Android中,我们无法自己构建onCreate()onAttach(),因此我们会在onCreateView()dat <- data.frame("Code"=c("XS1.1","W1.23","Kj1.9"),"Total"=c(9,3,2)) dat2 <- data.frame("Code"=rep(dat[,1],dat[,2]),"Total"=c(seq(1:dat[1,2]),seq(1:dat[2,2]),seq(1:dat[3,2]))) let startTime; const timer = typeof performance !== `undefined` && typeof performance.now === `function` ? performance : Date; const startButton = document.getElementById('start'); const stopButton = document.getElementById('stop'); const display = document.getElementById('display'); startButton.onclick = () => { console.debug('START') startTime = timer.now(); startButton.disabled = "disabled"; }; stopButton.onclick = () => { console.debug('STOP') var totalSeconds = Math.round((timer.now() - startTime) / 1000); var totalMinutes = Math.floor(totalSeconds / 60); var totalHours = Math.floor(totalSeconds / 60 / 60); var displaySeconds = totalSeconds - totalMinutes * 60; var displayMinutes = totalMinutes - totalHours * 60; var strDisplayTime = (totalHours > 0 ? (totalHours + '0:') : '') + (displayMinutes > 0 || totalHours > 00 ? ((displayMinutes >= 10 ? '' : '0') + displayMinutes + ':') : '00:00:') + ((displaySeconds >= 10 ? '' : '0') + displaySeconds) display.innerHTML = strDisplayTime; stopButton.disabled = "disabled"; }; 等中执行DI,但它并不意味着我们应该使用DI库来协助控制应用程序的流程。

答案 1 :(得分:2)

子组件与继承(扩展)类似,在您的情况下,用户组件和活动组件扩展App组件,但用户组件和活动组件之间没有关系,因此当您在活动中请求用户依赖时,它将失败。

子组件不能向其他子组件提供任何依赖关系。

相反,您可以将Activity组件作为User组件的子组件。这也将为您提供切换用户的灵活性。