Today I would like to talk about Dagger 2 , in particular, about dagger-android , Android Architecture Components , as well as about the problem that I encountered when using them. Probably, the post is not so much informative as philosophical, I immediately ask you not to throw slippers, because there are reasons for creating the post (at least subjective), I will tell about them under the cut.
Long wondered whether to write this post, but the internal balance was shaken, and therefore the post to be.
The thing is this: surely many of you have already used the above tools in your projects, or at least have played with them in order to understand what kind of an animal this is. So I finally came to the conclusion that I should use them in my project.
Now, what I wanted to achieve with these tools:
Now a bit of code for better understanding:
class App : DaggerApplication() { override fun applicationInjector(): AndroidInjector<out App> = DaggerAppComponent.builder().create(this) }
@Singleton @Component(modules = [ (AndroidSupportInjectionModule::class), (AppModule::class), (ActivityBuilder::class) ]) interface AppComponent : AndroidInjector<App> { @Component.Builder abstract class Builder : AndroidInjector.Builder<App>() }
@Module abstract class ActivityBuilder { @ActivityScope @ContributesAndroidInjector(modules = [MainActivityModule::class, FragmentProvider::class, RepositoryModule::class]) abstract fun bindMainActivity(): MainActivity }
@Module class RepositoryModule { @Provides @ActivityScope fun provideSomeDataRepository(socket: SocketService, restApi: RestApi, feedDao: FeedDao, userSettings: UserSettings): SomeDataRepository = SomeDataRepositoryImpl(socket, restApi, feedDao, userSettings)
@Inject lateinit var factory: MainViewModelFactory private lateinit var viewModel: MainViewModel viewModel = ViewModelProviders.of(this, factory) .get(MainViewModel::class.java)
class MainViewModelFactory @Inject constructor(private val someDataRepository: SomeDataRepository) : ViewModelProvider.Factory{ override fun <T : ViewModel?> create(modelClass: Class<T>): T { if (modelClass.isAssignableFrom(MainViewModel::class.java)) { return MainViewModelImpl(someDataRepository) as T } throw IllegalArgumentException(String.format("%s Not Found", modelClass.simpleName)) } }
class MainViewModelImpl @Inject constructor(someDataRepository: SomeDataRepository) : MainViewModel(), MainViewModel.Input, MainViewModel.Output
So, about the list, what I wanted to get from all these manipulations.
Everything is good, everything works, only now I noticed one feature (a little later it became obvious): After changing the configuration, Dagger creates dependencies again .
Because of the little development experience with these tools, it was decided to ask other developers for advice, to which I received answers that this situation is the norm, that the garbage collector will cope with this mess, and everything will work fine.
Referring to the title of the post, about "unpicked", it was read somewhere in issues by dagger (not a quote word for word, but the meaning is the same): "You are trying to absorb all the best of these two tools, I do not think that this is possible "
Of course, you can not use the dagger-android, and submit dependencies directly to the view model using AndroidViewModel (application: Applitaction) in passing, but this will not work, because the view model does not need to know about the Application class. For me, still a mystery - why this class exists at all. Can someone explain in the comments?
Summarizing all the above, I have one question: Can I do what I want? Is it possible to get rid of this uncontrollable creation of Dagger objects when changing configuration?
I will be glad to answer in the comments, thank you for your attention.
Source: https://habr.com/ru/post/350072/
All Articles